给出这个示例类:
class Example {
String str = "";
public synchronized boolean foo () { str = "foo"; }
public boolean bar() { str = "bar"; }
public synchronized boolean baz() { str = "baz"; }
}
从这个post可以看出,任何线程都可以调用bar
方法。假设线程T1
正在执行foo()
和线程T2
调用bar()
。即使bar()
已获得锁定,str
可以重新分配foo
吗?如果baz
调用T2
即使T2
正在执行foo
,那么同样的问题呢?
答案 0 :(得分:3)
你需要首先让str
易变,让线程能够看到彼此的变化,否则他们只会看到本地副本。
第二个问题是一个线程正在修改它,另一个线程读取它然后你将得到不一致的状态。因此,如果跨线程共享变量,则使其变为volatile,并且应在同步块/方法中进行任何修改。
所以回答你的问题:Can bar() reassign str even though foo has obtained a lock?
- >是。
同样适用于T2。但除非您同步bar
,否则您无法保证一致状态。
答案 1 :(得分:0)
假设线程T1正在执行foo()和线程T2调用 酒吧()。即使foo获得锁定,bar()还能重新分配str吗?
是肯定的。因为,即使foo()
已同步,bar()
也不会。线程T1
已获取类Example
对象的锁定,并且它的同步函数将被锁定,而不是
非同步的。
即使T1是T2,如果被T2调用baz也会出现同样的问题 在执行foo的过程中?
这一次,当baz()
函数同步时,如果T2
已经获得对T1
函数之一的访问权限,synchronized
将会等待foo()
Example
}}类{{1}}的对象。
答案 2 :(得分:0)
synchronized执行以下操作:if(假设)5个线程要求访问,4个线程处于保持状态,1个线程通过。你总是需要在某事上进行同步,因为有人需要成为监视器来检查行中有多少个线程,并且在当前线程完成后将被允许进入。
但是如果你没有这个同步块,没有人限制访问。这就像在俱乐部拥有最关键的保镖,而后门是广泛开放的。即使“俱乐部”具有同步访问权限,即使是最好的监视器(保镖)也无法阻止人们使用后门,如果他不知道的话。