2016-09-21 203 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举例与您的问题非常相关