Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 非静态线程作为静态函数的参数引发NullPointerException_Java_Multithreading_Static_Arraylist - Fatal编程技术网

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