我的問題如下:
為什么run()方法中的判斷陳述句是getCount()<13?
從輸出結果可以看出,程式最后到了count值為15的時候才結束。但是count值從13開始,run()方法就不會被呼叫了才對啊。
還是說這樣的運行結果和wait()及notifyAll()方法的使用有關,有大神能解釋一下嗎?
一、測驗類:
public class Test {
public static void main(String[] args) {
//創建一個PrintCopy類的物件
PrintCopy pc=new PrintCopy();
//將PrintCopy類的物件作為引數傳給一個Print物件
Print print=new Print(pc);
//新建3個執行緒,并同時取名為"A"、"B"、"C"
Thread t1=new Thread(print,"A");
Thread t2=new Thread(print,"B");
Thread t3=new Thread(print,"C");
//啟動執行緒
t1.start();
t2.start();
t3.start();
}
}
二、列印類:
public class PrintCopy
{
private int flag=1;
private int count=0;
public int getCount() {
return count;
}
public synchronized void printA() {
while(flag!=1) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(Thread.currentThread().getName());
flag=2;
count++;
System.out.print(count);
notifyAll();
}
public synchronized void printB() {
while(flag!=2) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(Thread.currentThread().getName());
flag=3;
count++;
System.out.print(count);
notifyAll();
}
public synchronized void printC() {
while(flag!=3) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(Thread.currentThread().getName());
flag=1;
count++;
System.out.print(count);
notifyAll();
}
}
class Print implements Runnable{
private PrintCopy pc;
public Print(PrintCopy pc) {
this.pc=pc;
}
public void run() {
//控制列印次數
while(pc.getCount()<13) {
if(Thread.currentThread().getName().equals("A")) {
pc.printA();
}
else if(Thread.currentThread().getName().equals("B")) {
pc.printB();
}
else if(Thread.currentThread().getName().equals("C")) {
pc.printC();
}
}
}
}
三、列印結果
A1B2C3A4B5C6A7B8C9A10B11C12A13B14C15
uj5u.com熱心網友回復:
因為printA,printB,printC是 并行且加鎖的,所以執行緒A判斷的count其實就是上輪A時執行的count的值,同理B,C。也就說最后1輪A執行緒getCount值為10然后進入等待喚醒,B執行緒getCount值為11然后進入等待喚醒,C執行緒getCount為值12然后進入等待喚醒。下輪A count變13跳出回圈,B count變14后跳出回圈,C count變15后跳出回圈。
uj5u.com熱心網友回復:
因為你自旋的時候沒有判斷 countuj5u.com熱心網友回復:
首先,你要知道,有三個執行緒(不算主執行緒和gc的話),分別是ABC當count=12時,剛剛列印完c12,從此時開始分析while(pc.getCount()<13)
對于B執行緒(運行pc.printB()方法,卡死在wait())
對于C執行緒(運行pc.printC()方法,卡死在wait())
對于A執行緒(運行pc.printA()方法,此時flag=1,count++,列印A13,flag置為2,最后notifyAll())
此時while(pc.getCount()<13)不成立,任何一個執行緒走到這里都會結束。但是BC執行緒此時剛付訓醒,在wait的代碼處醒來,因此還會列印B14,C15,等執行完pc.printB(),pc.printC(),才會走到while判斷count是否小于13,當然此時都不成立,所以也會終止。
不過我感覺,這樣子的話,不一定保證能輸出到15吧,13,14,15都有停止的可能,你可以多運行幾次試試看
uj5u.com熱心網友回復:
我的想法和你是一樣的,但是看到樓上那位兄弟的解釋,就感覺有點難懂。運行了很多次,它最后都是在15這里停止的。
uj5u.com熱心網友回復:
你可以嘗試一下,把你run方法中的B,C執行緒部分在執行完print以后sleep一會,看看列印結果會不會存在不同
uj5u.com熱心網友回復:
因為執行的速度原因從wait()到count++ ,前面還有2句陳述句要執行,而run()里面因為if else嵌套,所以喚醒陳述句以后馬上會執行getCount()<13,所以一般正常情況就不會發生count次序被打亂的情況。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/90443.html
標籤:Java SE
上一篇:for回圈如何保存中間查詢到資料,并且繼續回圈,我應該怎么去寫
下一篇:VSCode配置C#運行環境教程
