![](/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.