将使用多线程的程序转换为使用阻塞队列的程序

时间:2016-11-17 21:15:23

标签: java multithreading blockingqueue

我目前正在尝试将当前使用多线程,锁等的程序转换为使用阻塞队列的程序。重点是删除所有多线程代码。将有100个生产者线程。生产者线程都忙于生成事务对象(每个对象不同)并将它们放入队列。一个消费者线程将不断从队列中删除事务并处理它们。换句话说,永远循环。但是,消费者线程中永远存在的循环并没有成功。我想只使用一个消费者线程。并且使用我的代码,当输出行应该一直持续到程序停止时,我只得到一行输出。这是我的代码,任何帮助将得到赞赏并提前感谢。

import java.util.*;
import java.util.concurrent.*;

public class SynchBankTest
{
public static final int NACCOUNTS = 100;
public static final double INITIAL_BALANCE = 1000;
public static final int DELAY = 10;
public static final Transaction tr = new Transaction();

public static void main(String[] args)
{
  BlockingQueue<Transaction> queue = new ArrayBlockingQueue<>(30);
  Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE);

  for (int i = 0; i < NACCOUNTS; i++)
  {
     Runnable p = () -> {
        try
        {
           while (true)
           {
                queue.put(tr);
                Thread.sleep((int) (DELAY * Math.random()));
           }
        }
        catch (InterruptedException e)
        {
        }
     };
     Thread pt = new Thread(p);
     pt.start();
  }

     Runnable c = () -> {
        double amount = 0;
        int fromAcct = 0;
        int toAcct = 0;
        amount = tr.getAmount();
        fromAcct = tr.getFromAccount();
        toAcct = tr.getToAccount();
        bank.transfer(fromAcct, toAcct, amount);
     };
     Thread ct = new Thread(c);
     ct.start();
   }
  }
 class Transaction
 {
 private double amount;
 private int toAccount;
 private int fromAccount;
 private static final double MAX_AMOUNT = 1000;
 private Bank bank = new Bank(100, 1000);

 public Transaction()
 {
 }
 public int getToAccount()
 {
    toAccount = (int) (bank.size() * Math.random());
    return toAccount;
 }
 public int getFromAccount()
 {
    for (int i = 0; i < 100; i++)
    {
        fromAccount = i;
    }
    return fromAccount;

 }
 public double getAmount()
 {
    amount = MAX_AMOUNT * Math.random();
    return amount;
 }
}
class Bank
{
 private final double[] accounts;

 public Bank(int n, double initialBalance)
 {
   accounts = new double[n];
   Arrays.fill(accounts, initialBalance);
 }

 public void transfer(int from, int to, double amount)
 {
     if (accounts[from] < amount) return;
     System.out.print(Thread.currentThread());
     accounts[from] -= amount;
     System.out.printf(" %10.2f from %d to %d", amount, from, to);
     accounts[to] += amount;
     System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());
 }

 public double getTotalBalance()
 {
  try
  {
     double sum = 0;

     for (double a : accounts)
        sum += a;

     return sum;
  }
  finally
  {
  }
}

public int size()
{
   return accounts.length;
}
}

1 个答案:

答案 0 :(得分:0)

如上所述,消费者线程需要有一个无限循环,我没有。这解决了我的问题:

     Runnable c = () -> {
        try{
            while(true)
            {
                tr = queue.take();
                double amount = 0;
                int fromAcct = 0;
                int toAcct = 0;
                amount = tr.getAmount();
                fromAcct = tr.getFromAccount();
                toAcct = tr.getToAccount();
                bank.transfer(fromAcct, toAcct, amount);
            }
        }
        catch(InterruptedException e)
        {
        }
     };
     Thread ct = new Thread(c);
     ct.start();