将使用多线程的程序变成使用阻塞队列的程序
Turning a program using multi-threading into a program that uses blocking queues
我目前正在尝试将当前使用多线程、锁等的程序转换为使用阻塞队列的程序。重点是删除所有多线程代码。将有 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;
}
}
就像上面说的,消费者线程需要有一个无限循环,我没有。这解决了我的问题:
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();
我目前正在尝试将当前使用多线程、锁等的程序转换为使用阻塞队列的程序。重点是删除所有多线程代码。将有 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;
}
}
就像上面说的,消费者线程需要有一个无限循环,我没有。这解决了我的问题:
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();