同步方法无法按预期工作 [英] Synchronized method does not work as expected
问题描述
我有一个由两个线程共享的变量。这两个线程将对它进行一些操作。我不知道为什么每次执行程序时sharedVar的结果都不同。
I have a variable which is shared by two threads. The two threads will do some operations on it. I don't know why the result of sharedVar is different every time I execute the program.
public class Main
{
public static int sharedVar = 0;
public static void main(String[] args)
{
MyThread mt1 = new MyThread();
MyThread mt2 = new MyThread();
mt1.start();
mt2.start();
try
{
// wait for the threads
mt1.join();
mt2.join();
}
catch (InterruptedException e1)
{
e1.printStackTrace();
}
System.out.println(sharedInt); // I expect this value to be 20000, but it's not
}
}
以下是MyThread类
The following is the class "MyThread"
public class MyThread extends Thread
{
private int times = 10000;
private synchronized void addOne()
{
for (int i = 0; i < times; ++i)
{
Main.sharedVar ++;
}
}
@Override
public void run()
{
addOne();
}
}
sharedVar的最终结果有时是13735,12508,或18793;但从来没有20000,这是我期望的结果。该计划的另一个有趣的事情是时间= 1000。我总是得到2000作为最终结果。
The final result of sharedVar sometimes are 13735, 12508, or 18793; but never 20000, which is the result I expect. Another interesting thing about the program is when times=1000. I always get 2000 as the final result.
任何人都可以解释这种现象吗?
Can anyone explain this phenomenon?
推荐答案
synchronized方法保护资源 this
,这意味着您的代码相当于:
A synchronized method protects the resource this
that means that your code is equivalent to:
private void addOne()
{
synchronized(this)
{
for (int i = 0; i < times; ++i)
{
Main.sharedVar ++;
}
}
}
但你有两个对象调用哪个 addOne
方法。这意味着此
mt1.addOne
与此$ c $不同c> for
mt2.addOne
因此您没有公共同步资源。
But you have 2 objects for which addOne
method is called. That means this
for mt1.addOne
is not the same than this
for mt2.addOne
and therefore you don't have a common resource of synchronization.
尝试更改yout addOne
代码:
Try changing yout addOne
code to:
private void addOne()
{
synchronized(MyThread.class)
{
for (int i = 0; i < times; ++i)
{
Main.sharedVar ++;
}
}
}
你会看到预期的行为。如下面的评论所示,最好使用与 MyThread.class
不同的对象进行同步,因为类对象可以从许多点访问,而其他代码很容易尝试使用相同的对象进行同步。
And you will observe the expected behaviour. As the comments below suggest, it is better to use a different object than MyThread.class
for synchronization since class objects are accesible from many points and it is easy that other code may try to synchronize using the same object.
这篇关于同步方法无法按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!