抢占正在执行同步方法的线程
给出以下代码
class Test{
double x;
public void synchronized a()
{
x = 0;
//do some more stuff
}
public void b()
{
x = -1;
}
}
a() 中的线程在修改 x 的过程中是否可以被对同一对象调用 b() 的线程抢占?
同步方法不是像单个原子操作一样执行吗?
我相信另一种方式是可能的(b() 中的线程可以被在同一对象上调用 a() 的线程抢占,因为 b() 不受测试对象锁的保护)。
有人可以解释一下吗?
Give the following code
class Test{
double x;
public void synchronized a()
{
x = 0;
//do some more stuff
}
public void b()
{
x = -1;
}
}
Can the thread in a(), in the middle of modifying x be preempted by a thread that calls b() on the same object?
Isn't synchronized method be executed like one single atomic operation?
I believe the other way is possible(thread in b() can be preempted by the thread that calls a() on the same object since b() is not guarded my the Test object lock).
Can some one shed some light on this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
synchronized
仅阻止其他线程获取同一监视器。它不可能使操作原子化。特别是:b()
不同步,因此完全有可能一个线程正在执行a()
而另一个线程正在执行a()
同时执行b()
。synchronized
only stops other threads from acquiring the same monitor. It in no way makes the operation atomic. In particular:b()
isn't synchronized, so it's entirely possible for one thread to be executinga()
and another to be executingb()
at the same time.由于
b()
不同步,而a()
同步,因此有可能一个线程位于a()
中,而另一个线程位于a()
中。位于b()
中。因此,由于对x
的并行非同步访问,x
的值很可能会出现乱码。此外,如果您的代码如下所示:
并且两个线程都在同一个实例上运行,那么线程 1 [ 当前位于
a()
中的可能性就出现了被线程 2 抢占[当前在b()
中]。然而,线程1被抢占后,当线程2尝试进入
a()
方法时,JVM将不允许它;因为另一个线程[尽管没有运行]已经拥有了锁。因此,现在线程 2 将等待,直到线程 1 完成a()
的执行并返回。然后线程 2 [很可能]将被恢复并允许执行a()
。Since
b()
is not synchronized anda()
is, it is possible for one thread to be ina()
and the other to be inb()
. So the value ofx
will most possibly be garbled due to parallel non-synchronized access tox
.In addition, if your code were like this:
and both of your threads are running on the same instance then there arises a possibility of Thread 1 [ currently in
a()
being preempted by Thread 2 [currently inb()
].However after Thread 1 is preempted, as Thread 2 tries to enter the
a()
method, the JVM will not allow it; since another thread [albeit a non running one] already has the lock on it. Hence now Thread 2 will be made to wait until Thread 1 completes execution ofa()
and returns. Then Thread 2 will [most probably] be brought back to life and allowed execution ofa()
.