2016-11-17 68 views
1

我目前正試圖將當前正在使用多線程,鎖等的程序轉變爲使用阻塞隊列的程序。重點是刪除所有的多線程代碼。將有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

我沒有看到消費者線程中的任何循環。 (我假設'ct'是消費者線程。) – bradimus

+0

我明白你在說什麼。我想我一定非常專注於讓那個做這個循環的單一線程在​​那個時候對我沒有意義。謝謝。 – Jay

回答

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();