0

给定这个示例类:

class Example {
    String str = "";
    public synchronized boolean foo () { str = "foo"; }
    public boolean bar() { str = "bar"; }
    public synchronized boolean baz() { str = "baz"; }
}

从这篇文章中,很明显任何线程都可以调用该bar方法。假设线程T1正在执行foo()和线程T2调用bar()中。即使获得了锁也可以bar()重新分配吗?即使在执行过程中,如果被调用,同样的问题呢?strfoobazT2T2foo

4

3 回答 3

3

您需要str首先使线程成为 volatile 以便能够看到彼此的更改,否则他们将只能看到本地副本。

第二个问题是一个线程正在修改它,另一个线程读取它,那么您将获得不一致的状态。因此,如果一个变量是跨线程共享的,那么让它变得易变,并且任何修改都应该在一个同步的块/方法中进行。

所以回答你的问题:Can bar() reassign str even though foo has obtained a lock?->是的。

同样适用于 T2。但是除非您同步,否则您将无法保证一致的状态bar

于 2013-11-13T08:59:35.467 回答
0

假设线程 T1 正在执行 foo() 并且线程 T2 调用 bar()。即使 foo 获得了锁, bar() 是否可以重新分配 str ?

是的。因为,即使foo()是同步的,bar()也不是。线程T1已获得类对象的锁Example,它的同步函数将被锁定,而不是非同步函数。

即使 T1 正在执行 foo,如果 Baz 被 T2 调用,同样的问题又会怎样呢?

这一次,由于baz()函数是同步的, 如果已经获得了对 class 对象的函数之一(即)的访问权,T2则将等待。T1synchronizedfoo()Example

于 2013-11-13T09:35:03.950 回答
0

synchronized 执行以下操作:如果(假设)5 个线程正在请求访问,则 4 个被搁置,1 个被允许通过。您总是需要同步某些东西,因为需要有人担任监视器来检查行中有多少线程,并且一旦当前线程完成,下一个将被允许进入。

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

于 2013-11-13T13:27:13.580 回答