2016-09-21 152 views
0

我遇到了兩個線程似乎沒有正確同步的問題。我基本上有一個布爾值名稱「佔用」。當沒有線程啓動時,它被設置爲false。但是當一個開始,線程集佔用是真的我有一個類有線程(運行),他們調用下面的函數。多線程生產者/消費者同步問題

這是一個模擬銀行示例,它接收一定金額(初始餘額),然後隨機執行提款和存款。我的教授提到了一些有關從存款線索中提取信號的信號?這是如何運作的?退出線程,它應該運行,直到餘額爲兩個低,並等待存款線程。我應該怎麼做?

package bank; 

import java.util.Random; 
import bank.Bank; 
import java.util.concurrent.locks.ReentrantLock; 
import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.Condition; 

/** 
* 
* @author KJ4CC 
*/ 
public class Action { 

    private Lock accessLock = new ReentrantLock(); 
    private Condition cond = accessLock.newCondition(); 
    //private Condition withdraw = accessLock.newCondition(); 


    Random rand = new Random(); 
    Object lock = new Object(); 
    Bank getBalance = new Bank(); 

    public void widthdrawl(int threadNum) throws InterruptedException { 
     int amount = rand.nextInt(50); 
      accessLock.lock(); 

      if (getBalance.getbalance() > amount) { 

       getBalance.setBalance(getBalance.getbalance() - amount); 

       System.out.println("\t\t\tThread " + threadNum + " withdrawls " + amount + "\t Balance is " + getBalance.getbalance()); 

      } else { 

       System.out.println("\t\t\tThread " + threadNum + " Failed to withdrawl " + amount + "\t Balance is " + getBalance.getbalance()); 
       cond.await(); 

      } 


      accessLock.unlock(); 
      Thread.sleep(rand.nextInt(5)); 

    } 

    public void deposit(int threadNum) throws InterruptedException { 
     int amount = rand.nextInt(200); 
     accessLock.lock(); 


      getBalance.setBalance(getBalance.getbalance() + amount); 
      System.out.println("Thread " + threadNum + " Deposits " + amount + "\t\t\t\t Balance is " + getBalance.getbalance()); 
      Thread.sleep(rand.nextInt(100)); 

      cond.signal(); 
      accessLock.unlock(); 


    } 
} 
+0

嘗試結帳一個BlockingQueue。 –

回答

0

首先,你必須標記你occupid變量volatile。如果沒有這個關鍵字,那麼一個線程中的變量值將不會在另一個線程中可見。

其次,您試圖爲bank實體實施外部同步策略。這樣的想法基本上不好:如果有人使用相同的bank沒有正確同步它會打破內部銀行狀態。最好實施內部同步政策,並允許銀行自行保護其狀態。

E.g. Bank類的API可能是這樣

class Bank { 
    double synchronize getBalance() { ... } 
    void synchronize deposit(double amount) { ... } 
    void synchronize widthdrawl(double amount) throw BankException { ... } 
} 

採用這種設計的內部Bank狀態始終是一致的,並任何Bank用戶將等待自動完成目前的銀行操作。

+0

感謝您的提示。 –

+1

他不需要'synchronized',他使用'Locks'。他只是用錯了他們。 – Kayaman

+0

@Kayaman實際上,他並不需要Action類中的任何鎖。整個設計並不好我正在說什麼,並提出更好更簡單的設計 –

4

您的LockCondition用法錯誤。您撥打lock()時不需要隨時撥打unlock(),並且您撥打signal()時沒有任何人撥打await()

查看documentation舉例與您的問題非常相關