Java 非静态线程作为静态函数的参数引发NullPointerException
我正在使用一个应该在后台运行一些作业的程序。 在应用程序关闭之前,它应该在实际关闭之前等待剩余的作业完成,所以我用一个静态数组列表创建了一个类来存储正在运行的线程,这样我就可以从我的应用程序的全局范围访问所有这些作业,并获得我想要的结果Java 非静态线程作为静态函数的参数引发NullPointerException,java,multithreading,static,arraylist,Java,Multithreading,Static,Arraylist,我正在使用一个应该在后台运行一些作业的程序。 在应用程序关闭之前,它应该在实际关闭之前等待剩余的作业完成,所以我用一个静态数组列表创建了一个类来存储正在运行的线程,这样我就可以从我的应用程序的全局范围访问所有这些作业,并获得我想要的结果 public class BackgroundWorker extends javax.swing.JDialog { private static ArrayList thlist; public static void DoThisThin
public class BackgroundWorker extends javax.swing.JDialog {
private static ArrayList thlist;
public static void DoThisThingAndDontBotherMe(Thread t) {
thlist.add(t); // :3
t.start();
}
public static void WaitForJobsToBeDone() {
for(Object o : thlist.toArray()) {
if(!((Thread) o).isAlive()) {
thlist.remove(o);
}
}
if(thlist.isEmpty())
return;
for(int i = 0; i < thlist.size(); i++) {
try {
((Thread) thlist.get(i)).join();
} catch(InterruptedException e) { System.err.println("Crap. A thread failed!! X.x");
}
}
}
程序在以“:3”注释的行中抛出空指针异常,就好像对new Thread(){}的调用是空指针>>
PS:如果我确实以这种方式创建了一个新的线程变量,而不调用我的类,然后调用它的start()方法,那么线程会按预期的方式完成它的工作。但我需要将这些线程存储在一个全局可访问列表中,以便在关闭应用程序之前等待它完成。
PS 2:上面的函数名只是代表性的,不是我在应用程序中使用的名称。我不会对函数和类型使用长名称
我不考虑哪一个静态/非静态规则?x、 x当您调用
BackgroundWorker.dotHisthingandDontOtherme(新线程()…
时,您是否确保您的数组列表thlist;
已初始化?您需要实例化thlist
private static ArrayList thlist = new ArrayList();
最好在此处使用泛型:
private static ArrayList<Thread> thlist = new ArrayList<>();
private static ArrayList thlist=new ArrayList();
(如果使用Java 7)或:
private static ArrayList thlist=new ArrayList();
如果没有。您需要初始化列表:
ArrayList myList = new ArrayList();
你在试图重新发明一种新方法 您可以通过以下操作(使用直接从JavaDoc页面获取的shutdown方法)以更有效、更惯用的方式解决问题:
你忘记初始化了
ArrayList list = new ArrayList();
thlist
未初始化thlist
初始化在哪里?显然这并不能直接回答OP的问题,但他们的意图相当清楚,我相信这是解决他的问题的一种更有效的方法(更不用说让下一个人看到他的代码时更容易维护)。无论如何,我都添加了一个具体的例子。我推荐了一些逻辑,BackgroundWorker有一些非静态的可实例化的东西,可以根据静态信息在屏幕上显示进度条;@Felype我不知道为什么这会阻止你使用ExecutorService
。Tyvm伙计,这个答案完美地澄清了我的问题。
ArrayList myList = new ArrayList();
public class BackgroundWorker extends javax.swing.JDialog
{
private final ExecutorService _executorService = Executors.newFixedThreadPool(NUMBER_OF_CONCURRENT_OPERATIONS);
public void doThisThingAndDontBotherMe(Runnable runnable)
{
_executorService.execute(runnable);
}
public void waitForJobsToBeDone()
{
_executorService.shutdown();
try
{
// Wait a while for existing tasks to terminate
if (!_executorService.awaitTermination(60, TimeUnit.SECONDS))
{
_executorService.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!_executorService.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
}
catch (InterruptedException ie)
{
// (Re-)Cancel if current thread also interrupted
_executorService.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
ArrayList list = new ArrayList();