为什么这段代码不是线程安全的?
在下面的代码片段中,将 doThings() 方法声明为静态将使该类成为线程安全的。原因是如果启动多个 TestSeven 线程并且由于 x 是静态变量,可能会发生竞争条件?
public class TestSeven extends Thread{
private static int x;
public synchronized void doThings(){
int current = x;
current++;
x = current;
}
public void run(){
doThings();
}
public static void main(String args[]){
TestSeven t = new TestSeven();
Thread thread = new Thread(t);
thread.start();
}
}
In code snippet below, declaring the doThings() method as static would make the class thread-safe. Is the reason for this that if multiple TestSeven threads are started and since x is a static variable a race condition could occur ?
public class TestSeven extends Thread{
private static int x;
public synchronized void doThings(){
int current = x;
current++;
x = current;
}
public void run(){
doThings();
}
public static void main(String args[]){
TestSeven t = new TestSeven();
Thread thread = new Thread(t);
thread.start();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
是的,完全正确。
doThings
的同步
本质只会阻止它被同一个实例上的多个线程同时调用。变量x
是在全局基础上共享的,而不是在每个实例的基础上共享的,因此它是不安全的。在现实世界中,可以将其想象为一间有几扇门的浴室 - 有人可以打开一扇门然后将其锁上,但这并不能阻止其他人通过另一扇门进入......
Yes, exactly. The
synchronized
nature ofdoThings
only stops it from being called by multiple threads concurrently on the same instance. The variablex
is shared on a global basis, not on a per-instance basis, therefore it's unsafe.In real world terms, think of it as a bathroom with several doors - someone can open one door and then lock it, but that doesn't stop someone else from coming in via a different door...
我认为如果该方法不是静态的,每个 TestSeven 对象将使用自己的锁进行同步 - 因此每个锁将有一个线程,并且它们中的任何一个都不必等待另一个线程。如果该方法被声明为静态,我似乎记得它们锁定了相应的 Class 对象。
I think if the method is not static, each TestSeven object would synchronize using its own lock - so there will be one thread per lock, and none of them will have to wait for another thread. If the method is declared static, I seem to recall they lock on the corresponding Class object.
只是补充一点,如果您将方法 doThings 声明为静态,它将在类锁而不是实例锁上同步,因此它将是防弹的。
Just to add that if you declare method doThings static, it will synchronize on the class lock rather than instance lock so then it will be bullet-proof.
是的。这里可能会出现竞争条件。当您使方法同步而不是您的变量时。因此,根据竞争条件的定义,一个线程将读取变量的值,而同步方法中的其他线程可以写入它。因此将会存在竞争条件。
yes. Race condition could occur in this. As you are making the method synchronized not your variable. So according to the definition of the race condition, one thread will read the value of variable while other in synchronized method can write it. So a race condition will be there.
您在
this
上同步代码,即在 TestSeven 的该实例上同步代码。x
是静态的,因此不会被锁定。这就是为什么您可以从不同的实例访问相同的x
。为了解锁该属性,您需要在类上进行同步。You synchronize your code on
this
, meaning on that instance of TestSeven.x
is static, so it will not be locked. That is why, from different instances, you can access the samex
. In order to det a lock on that attribute, you'll need to synchronize on the class.