从非同步/同步上下文修改实例变量

时间:2013-11-13 08:56:33

标签: java multithreading

给出这个示例类:

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,那么同样的问题呢?

3 个答案:

答案 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个线程通过。你总是需要在某事上进行同步,因为有人需要成为监视器来检查行中有多少个线程,并且在当前线程完成后将被允许进入。

但是如果你没有这个同步块,没有人限制访问。这就像在俱乐部拥有最关键的保镖,而后门是广泛开放的。即使“俱乐部”具有同步访问权限,即使是最好的监视器(保镖)也无法阻止人们使用后门,如果他不知道的话。