您的位置:首页 > 编程语言 > Java开发

java synchronized关键字this与this.Class的区别

2017-10-17 22:02 399 查看
刚刚接触多线程,可以说没啥经验。今天研究了一天,写了点实验的代码,顺便总结一下synchronized()括号里面关键字的区别。本文中会大量参考之前《代码模块化和可读性的tradeoff》中的代码进行讨论,所以建议同时打开

就不单独讨论静态方法的同步了,他是instance变量(final TrySimpleLock simpleLock = new TrySimpleLock();)、object引用(private Object syncObject = new Object())、static函数(synchronized static trySync(){})以及class literal类本身同步(synchronized(this.getClass()))其中一种。本文主要讨论第一种和第四种

其实很简单在实例化两个对象的时候,如

public static void main(String[] args) {
final TrySimpleLock simpleLock = new TrySimpleLock();
final TrySimpleLock simpleLockSecond = new TrySimpleLock();
new Thread(() -> simpleLock.f()).start();
simpleLock.g();
new Thread(() -> simpleLockSecond.h()).start();
}


如果使用同步实例对象

private void synchronizedLoop() {
synchronized (this) {
loop();
}
}


进程在thread-0和thread-1之间是同时进行的,结果如下

main: Negative in g()
main: Positive in g()
Thread-0: Negative in f()
main: Positive in g()
main: Positive in g()
main: Negative in g()
Thread-0: Positive in f()
Thread-1: Negative in h()
Thread-1: Positive in h()
Thread-1: Positive in h()
Thread-0: Positive in f()
Thread-0: Positive in f()
Thread-1: Positive in h()
Thread-0: Negative in f()
Thread-1: Negative in h()


至于为什么他们会等main跑完再执行,期初不是很理解,但仔细想了一下,这里要看main函数里的顺序:先走到
new Thread(() -> simpleLock.f()).start()
启动新线程,然后main走到
simpleLock.g()
此时main已经走到positive了,而锁已经锁住了simpleLock这个实例,等到下一次main的negative出现的时候才会继续执行为f()启动的新线程。而simpleLockSecond这个实例执行的
new Thread(() -> simpleLockSecond.h()).start()
独立于simpleLock,所以h()和f()会一起执行

接着上面synchronized()括号中内容的讨论,如果同步该类

private void synchronizedLoop() {
synchronized (this.getClass()) {
loop();
}
}


那么整个结果就将井然而有序

main: Negative in g()
main: Positive in g()
Thread-0: Negative in f()
main: Positive in g()
main: Positive in g()
Thread-0: Positive in f()
main: Negative in g()
Thread-1: Negative in h()
Thread-0: Positive in f()
Thread-0: Positive in f()
Thread-0: Negative in f()
Thread-1: Positive in h()
Thread-1: Positive in h()
Thread-1: Positive in h()
Thread-1: Negative in h()


愚以为在一般系统中的大部分业务场景下,都需要针对Class进行进行同步锁止,这样在不同地方的调用才不会造成混乱。针对同步锁造成的开销,会在以后的学习中慢慢体会
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: