2016-09-21 12 views
0

正しく同期されていない2つのスレッドに関する問題が発生しています。私は基本的にブール値の名前は "占領"を持っています。スレッドが起動していない場合はfalseに設定されます。しかし、スレッドが起動すると、占有されているスレッドセットは真です。スレッド(実行)を持つクラスがあり、以下の関数を呼び出します。マルチスレッドプロデューサ/コンシューマ同期の問題

これは金額(初期残高)を取り込んで引き出しと預金をランダムに実行するモックバンクの例です。私の教授は、預金スレッドに退会スレッドを通知することについて何か言及していますか?それはどのように機能するのですか?引き出しのスレッドは、残高が2になるまで実行し、入金スレッドを待ちます。それはどうしたらいいですか?

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をマークする必要があります。このキーワードを変更しないと、あるスレッドの変数値は別のスレッドには表示されません。

第2に、bankエンティティの外部同期ポリシーを実装しようとしています。そのようなアイデアは基本的には良いことではありません。誰かが同じ同期を使わずにbankを使用すると、内部の銀行状態が破綻します。内部同期ポリシーを実装して、銀行が自らの状態を守ることをお勧めします。

など。 BankクラスのAPIは、任意のBankユーザーは自動的に現在のバンクの動作を終了することを待ちます。この

class Bank { 
    double synchronize getBalance() { ... } 
    void synchronize deposit(double amount) { ... } 
    void synchronize widthdrawl(double amount) throw BankException { ... } 
} 
内部 Bank状態は常に一貫してこの設計により

等であってもよいです。

+0

チップをありがとう。 –

+1

彼は '同期'は必要ありません、彼は 'ロック 'を使用しています。彼はちょうどそれらを間違って使っている。 – Kayaman

+0

@Kayaman実際、彼はActionクラスではロックを必要としません。デザイン全体が私が言っていることは良くなく、よりシンプルなデザインを提案しました。 –

4

LockCondition使い方が間違っています。 lock()に電話をして、unlock()をどこにでも呼び出す必要はありません。await()と呼ばれることなく、signal()に電話しています。

の場合はと非常によく似ています。documentationを参照してください。