![](/img/trans.png)
[英]What happens when a synchronized method is called by a thread via another class?
[英]Class has 2 synchronized methods..when a thread is inside second method can another thread enter into first method?
我知道之前曾问过“同时执行两个同步方法”问题,给出的答案是“否。只有一个线程可以持有对象的锁。然后只有那个线程才能在该对象上输入同步方法。 “。 但是,如果它是真的,那么请帮助我理解以下代码的输出:
public class SynchronizationMistake {
public int count;
public synchronized int getCount()
{
return count;
}
public synchronized String incrementCount()
{
count++;
return"";
}
public static void main (String args[])
{
SynchronizationMistake syn = new SynchronizationMistake();
Thread first = new Thread(syn.new readIncrementCount(syn),"First");
Thread second = new Thread(syn.new readIncrementCount(syn), "Second");
Thread third = new Thread(syn.new readIncrementCount(syn), "Third");
first.start();
second.start();
third.start();
}
private class readIncrementCount implements Runnable
{
SynchronizationMistake syn;
readIncrementCount(SynchronizationMistake syn)
{
this.syn = syn;
}
@Override
public void run() {
System.out.println("I am "+Thread.currentThread().getName()+".Count is "+ syn.getCount());
System.out.println("I am "+Thread.currentThread().getName()+".Incrementing count now"+syn.incrementCount());
System.out.println("I am "+Thread.currentThread().getName()+". After Increment Count is "+ syn.getCount());
}
}
}
Output is :
I am First.Count is 0
I am First.Incrementing count now
I am First. After Increment Count is 1
I am Third.Count is 0
I am Second.Count is 0
I am Third.Incrementing count now
I am Second.Incrementing count now
I am Third. After Increment Count is 3
I am Second. After Increment Count is 3
每次我运行此程序时,输出都会变化。 我的疑问是当第二/第三线程获得CPU时,为什么它没有将“ count”读为1(由第一线程更新)? 换句话说,当第一个线程锁定了“ syn”并正在将计数更新为1时,第二个/第三个线程如何设法进入“ getCount”方法。
语句System.out.println("I am "+Thread.currentThread().getName()+".Count is "+ syn.getCount());
不是以原子方式执行的。 syn.getCount()
部分可以在println
之前执行。 您的示例中似乎也发生了这种情况。 所有线程首先执行syn.getCount()
,当时计数仍为0,然后再执行其余操作。
您发布的该特定执行的结果是,所有三个线程都读取值为零的计数器,但是线程一有机会在其他线程之前完成其所有输出,即,对计数器的访问已正确同步,但是稍后的打印显示较旧的值归因于输出缓冲。
尝试在第一个线程开始之后进入睡眠状态,这种情况不太可能再次发生。
正如Henry提到的,所有线程都可以首先执行syn.getCount(),然后执行syn.incrementCount。 我已经稍微修改了您的代码以更改println语句,从而获得了更好的画面...
public class SynchronizationMistake {
public int count;
public synchronized int getCount()
{
return count;
}
public synchronized String incrementCount() {
System.out.println("I am " + Thread.currentThread().getName() + ", incrementing the count from " + count);
count++;
System.out.println("I am " + Thread.currentThread().getName() + ", incremented the count to " + count);
return"";
}
public static void main (String args[])
{
SynchronizationMistake syn = new SynchronizationMistake();
Thread first = new Thread(syn.new readIncrementCount(syn),"First");
Thread second = new Thread(syn.new readIncrementCount(syn), "Second");
Thread third = new Thread(syn.new readIncrementCount(syn), "Third");
first.start();
second.start();
third.start();
}
private class readIncrementCount implements Runnable
{
SynchronizationMistake syn;
readIncrementCount(SynchronizationMistake syn)
{
this.syn = syn;
}
@Override
public void run() {
System.out.println("Current count is " + syn.getCount());
System.out.println(syn.incrementCount());
System.out.println("Current count is " + syn.getCount());
}
}
}
不同的输出如下所示...
输出#1:
Current count is 0
I am Second, incrementing the count from 0
Current count is 0
I am Second, incremented the count to 1
Current count is 1
I am First, incrementing the count from 1
I am First, incremented the count to 2
Current count is 2
Current count is 2
I am Third, incrementing the count from 2
I am Third, incremented the count to 3
Current count is 3
输出#2:
Current count is 0
Current count is 0
Current count is 0
I am Second, incrementing the count from 0
I am Second, incremented the count to 1
I am Third, incrementing the count from 1
I am Third, incremented the count to 2
I am First, incrementing the count from 2
I am First, incremented the count to 3
Current count is 3
Current count is 3
Current count is 3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.