java 调用 join() 时线程为空
java threads are null when join() is called
作为家庭作业,我正在为管理多个执行事务的线程的服务器编写一个 stop() 方法。 Stop() 应该 1. 向命令队列提交停止命令和 2. 在所有线程上调用 join() 以便事务有机会完成。
但是,join() 没有按预期工作。当我尝试调用 join() 时,出现 NullPointerException。我将服务器线程修改为在提交停止命令后等待一秒钟,但当我应该使用 join() 时,这是一个糟糕的替代方法。
public void stop() throws InterruptedException {
// TODO Auto-generated method stub
System.out.println("server stop()");
for (CommandExecutionThread thread : threads) {
System.out.println(threads.length);
}
for (CommandExecutionThread thread : threads) {
Command e = new CommandStop();
queue.add(e);
}
for (CommandExecutionThread thread : threads) {
if (thread != null)
{
thread.join();
}
if (thread == null)
{
System.out.println("NULL thread"); //threads are always null at this point
}
}
for (CommandExecutionThread thread : threads) {
System.out.println(threads.length);
}
wait(1000);//simulate the wait that I would have had from join()
}
CommandExecutionThreads poll() 命令来自 commandQueue,当它遇到停止命令时,它 returns:
public void run() {
while (true) {
synchronized (commandQueue) {
while (commandQueue.isEmpty()) {
try {
commandQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}//end while(commandQueue.isEmpty())
}//end synchronized(commandQueue)
Command c;
synchronized (commandQueue) {
c = commandQueue.poll();
if (c.isStop()==true)
{
System.out.println("\tSTOP");
return;
}
else
{
//System.out.println("\tTRANSACTION");
}
if (executeCommandInsideMonitor) {
try {
c.execute(bank);
} catch (InsufficientFundsException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
commandQueue.notifyAll();
} // end sync commandQueue
} //end while(true)
}//end run()
我在创建银行服务器时更早地初始化了我的线程数组。当命令可用时,线程自己将命令从队列中拉出。出于诊断目的,我打印了 thread.isAlive() 并且有效。当我进入停止方法时,thread.isAlive() 抛出一个空指针错误:
public class BankServerImpl implements BankServer {
Queue<Command> queue = new LinkedList<Command>();
CommandExecutionThread[] threads;
boolean executeCommandInsideMonitor;
Bank bank;
/**
* Constructor for BankServerImpl, which implements BankServer
*
* @param bank
* @param serverThreads
* @param executeCommandInsideMonitor
*/
public BankServerImpl(Bank bank, int serverThreads, boolean executeCommandInsideMonitor) {
this.bank = bank;
this.executeCommandInsideMonitor = executeCommandInsideMonitor;
threads = new CommandExecutionThread[serverThreads];
for(CommandExecutionThread thread : threads) {
thread = new CommandExecutionThread(bank, queue, executeCommandInsideMonitor);
thread.start();
System.out.println(thread.isAlive());
}
}
创建线程时,永远不会将它们插入到数组中。
for(CommandExecutionThread thread : threads) {
thread = new CommandExecutionThread(bank, queue, executeCommandInsideMonitor);
thread.start();
System.out.println(thread.isAlive());
}
此代码不会导致更新数组。你需要这样的东西:
for (int i = 0; i < serverThreads; i += 1) {
CommandExecutionThread newThread = new CommandExecutionThread(bank, queue, executeCommandInsideMonitor);
threads[i] = newThread;
newThread.start();
System.out.println(newThread.isAlive());
}
作为家庭作业,我正在为管理多个执行事务的线程的服务器编写一个 stop() 方法。 Stop() 应该 1. 向命令队列提交停止命令和 2. 在所有线程上调用 join() 以便事务有机会完成。
但是,join() 没有按预期工作。当我尝试调用 join() 时,出现 NullPointerException。我将服务器线程修改为在提交停止命令后等待一秒钟,但当我应该使用 join() 时,这是一个糟糕的替代方法。
public void stop() throws InterruptedException {
// TODO Auto-generated method stub
System.out.println("server stop()");
for (CommandExecutionThread thread : threads) {
System.out.println(threads.length);
}
for (CommandExecutionThread thread : threads) {
Command e = new CommandStop();
queue.add(e);
}
for (CommandExecutionThread thread : threads) {
if (thread != null)
{
thread.join();
}
if (thread == null)
{
System.out.println("NULL thread"); //threads are always null at this point
}
}
for (CommandExecutionThread thread : threads) {
System.out.println(threads.length);
}
wait(1000);//simulate the wait that I would have had from join()
}
CommandExecutionThreads poll() 命令来自 commandQueue,当它遇到停止命令时,它 returns:
public void run() {
while (true) {
synchronized (commandQueue) {
while (commandQueue.isEmpty()) {
try {
commandQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}//end while(commandQueue.isEmpty())
}//end synchronized(commandQueue)
Command c;
synchronized (commandQueue) {
c = commandQueue.poll();
if (c.isStop()==true)
{
System.out.println("\tSTOP");
return;
}
else
{
//System.out.println("\tTRANSACTION");
}
if (executeCommandInsideMonitor) {
try {
c.execute(bank);
} catch (InsufficientFundsException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
commandQueue.notifyAll();
} // end sync commandQueue
} //end while(true)
}//end run()
我在创建银行服务器时更早地初始化了我的线程数组。当命令可用时,线程自己将命令从队列中拉出。出于诊断目的,我打印了 thread.isAlive() 并且有效。当我进入停止方法时,thread.isAlive() 抛出一个空指针错误:
public class BankServerImpl implements BankServer {
Queue<Command> queue = new LinkedList<Command>();
CommandExecutionThread[] threads;
boolean executeCommandInsideMonitor;
Bank bank;
/**
* Constructor for BankServerImpl, which implements BankServer
*
* @param bank
* @param serverThreads
* @param executeCommandInsideMonitor
*/
public BankServerImpl(Bank bank, int serverThreads, boolean executeCommandInsideMonitor) {
this.bank = bank;
this.executeCommandInsideMonitor = executeCommandInsideMonitor;
threads = new CommandExecutionThread[serverThreads];
for(CommandExecutionThread thread : threads) {
thread = new CommandExecutionThread(bank, queue, executeCommandInsideMonitor);
thread.start();
System.out.println(thread.isAlive());
}
}
创建线程时,永远不会将它们插入到数组中。
for(CommandExecutionThread thread : threads) {
thread = new CommandExecutionThread(bank, queue, executeCommandInsideMonitor);
thread.start();
System.out.println(thread.isAlive());
}
此代码不会导致更新数组。你需要这样的东西:
for (int i = 0; i < serverThreads; i += 1) {
CommandExecutionThread newThread = new CommandExecutionThread(bank, queue, executeCommandInsideMonitor);
threads[i] = newThread;
newThread.start();
System.out.println(newThread.isAlive());
}