我試圖了解如何實作 Threads 爭議全域變數。在我的實作中,我創建了 2 個變數,并且我希望 4 個 Threds(例如)通過遞減來對其進行爭議。
第一個問題是我實作消費的方式總是遵循一個順序(第一個執行緒減少片狀冰淇淋,第二個執行緒減少巧克力冰淇淋)。
有什么辦法可以改進這個規則嗎?
而且我不想知道使用 CountDownLatch 的最佳位置是什么
public class IceCream implements Runnable {
private static int flake = 1;
private static int chocolate = 1;
@Override
public void run() {
buyIceCream();
}
private void synchronized buyIceCream() {
try {
if(IceCream.flake>0) {
System.out.println("");
System.out.println("successfully purchased " Thread.currentThread().getName());
Thread.sleep(200);
IceCream.flake--;
System.out.println("");
}
else if(IceCream.chocolate>0) {
System.out.println("");
System.out.println("successfully purchased " Thread.currentThread().getName());
Thread.sleep(200);
IceCream.chocolate--;
System.out.println("");
}
else {
System.out.println("No more ice cream " Thread.currentThread().getName());
}
}
catch(Exception e) {
}
}
}
public static void main(String[] args) throws InterruptedException {
IceCream c = new IceCream();
Thread[] t = new Thread[4];
for(int i = 0; i<t.length; i ) {
t[i] = new Thread(c);
t[i].setName("Kid" i);
t[i].start();
t[i].join();
}
}
uj5u.com熱心網友回復:
這是個錯誤:
t[i].start();
t[i].join();
在join()執行緒結束之前呼叫不會回傳,因此您的程式永遠不會允許多個執行緒同時運行。您可以通過撰寫兩個單獨的回圈來修復錯誤。第一個創建并啟動所有執行緒,然后第二個加入所有執行緒。
for(int i = 0; i<t.length; i ) {
t[i] = new Thread(c);
t[i].setName("Kid" i);
t[i].start();
}
for(int i = 0; i<t.length; i ) {
t[i].join();
}
這是另一個錯誤:
public void run() {
buyIceCream();
}
private void synchronized buyIceCream() {
...
}
將執行緒所做的所有事情包裝在一個synchronized方法中是另一種確保不允許兩個執行緒同時運行的方法。
至少,您應該從塊中洗掉sleep()呼叫:synchronized
private void buyIceCream() {
String message = "No more ice cream ";
synchronized (this) {
if(IceCream.flake>0) {
IceCream.flake--;
message = "Ice cream flake purchased by" Thread.currentThread().getName();
}
else if(IceCream.chocolate>0) {
IceCream.chocolate--;
message = "Chocolate ice cream purchased by" Thread.currentThread().getName();
}
}
System.out.println(message);
try {
Thread.sleep(200);
}
catch(Exception e) {
System.out.println("Never, EVER, completely ignore an exception.");
}
}
I also moved the System.out.println() call out of the synchronized block because I know that the characters printed by any single call will not be interleaved with characters printed by a single call from a different thread. (See https://stackoverflow.com/a/9459743/801894)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/447432.html
