我想更好地理解线程进入synchronized(this)
块vs synchronized(someObjectReference)
块时实际发生的机制。
synchronized (this) {
// Statement 1
// Statement 2
}
synchronized (someObjectReference) {
// Statement 1
// Statement 2
}
据我理解:(我错过了什么?我错了吗?)
someObjectReference
上进行同步时:
还有哪些其他技工?
synchronized (objectReference) {
// Statement 1 dealing with someObjectReference
// Statement 2 not dealing with someObjectReference
}
在上面的示例中,将不处理mutex
的语句添加到synchronized块中是否有意义?
答案 0 :(得分:1)
将两者混合在一起时只会有所不同。
synchronized(foo)
的单一基本规则是,在任何给定时间,只有一个线程可以位于同一synchronized(foo)
的{{1}}块中。那是它。(唯一值得一提的警告是,一个线程可以位于同一foo
的几个嵌套synchronized(foo)
块内。)
如果某些代码在foo
块内,并且某些代码在synchronized(foo)
块内,那么这些代码片段可以同时运行 - 但是你不能让两个代码运行代码synchronized(bar)
同时阻止。
答案 1 :(得分:0)
同步基本上意味着程序请求对指定对象进行锁定...如果一个线程无法进入任何同步块,那么这意味着任何其他线程已经锁定了指定的对象。代码的指定如果成功获取锁,则该区域内的线程可以进入..
In both cases, only 1 thread can access synchronized block at a time
- 取决于要锁定的可用对象
答案 2 :(得分:0)
在这两种情况下,一次只有1个线程可以访问同步块
不是真的。例如,当同步“this”时,如果2个线程有2个不同的同一类实例,则它们可以访问同一个块。但是,是的,对于一个实例,只有一个访问块。此
上的任何同步块也只有一个访问权限“已同步”表示只有一个线程可以访问同一实例上的任何同步块。因此,如果您在2个不同的源文件中有2个同步块,但在同一个实例上,如果其中一个块中有一个线程,则另一个线程无法访问两个同步块
关于“在同步块中做什么”:只做处理同步对象的事情。任何其他不需要同步的指令都会锁定资源,这可能会造成瓶颈
答案 3 :(得分:0)
关于this
同步的一个重要注意事项是处理可见性问题。假设您有一个班级A
,它会在this
上同步。使用A
的任何代码都引用了用于锁定的对象A
。这意味着A
的用户如果也锁定A
实例,则可能会创建死锁。
public class A implements Runnable {
public void run() {
synchronized (this) {
// something that blocks waiting for a signal
}
//other code
}
}
public class DeadLock {
public void deadLock() {
A a = new A();
Thread t = new Thread(a);
t.start();
Thread.sleep(5000); //make sure other thread starts and enters synchronized block
synchronized (a) {
// THIS CODE BLOCK NEVER EXECUTES
// signal a
}
}
}
如果你总是在私有成员变量上同步,你知道你是唯一一个使用该引用作为锁的人。