Java奇怪的线程终止

发布于 2024-10-26 07:52:47 字数 804 浏览 1 评论 0原文

我有一个运行多个线程的系统 - 我的主线程只是检查是否有作业要做,如果有,它会调用将执行它的子线程(notifyAll()) 。之后,子线程只是wait(),直到有一些新任务为止。

实际上,线程系统运行可靠,但是在较长的运行时间(3-5小时)之后,一些子线程在没有警告或错误的情况下就死掉了。他们只是一个接一个地退出——但同样只有 2-x 小时的时间范围。我使用 jconsole 来检查这种现象,哪些线程正在运行以及它们如何消失。

此外,主线程每秒都在执行,但子线程主要是 wait() ,根本不经常使用(因为测试环境中没有那么多任务)。

我能想到的唯一原因是,JVM 关闭子线程,因为它们不经常使用?

我将非常感谢您的帮助!

PS 所有线程都没有定义为守护进程,主线程工作正常!

编辑

感谢您的回答,但我实际上使用这个循环。

public void addTask (Task in_task) throws InterruptedException {
        synchronized (tasks) {
              while (tasks.size() == MAXIMUM_NUMBER_OF_TASKS) {
                   tasks.wait();
              }
              tasks.offer(in_task);
              tasks.notifyAll();
        }
}

我使用这个循环,以便只执行一些特殊数量的任务。

I have a system with multiple threads running - my main-thread just checks if there are jobs to be done and if there are some, it calls the sub-threads (notifyAll()) who will execute it. After that, the sub-threads just wait() until there are some new tasks.

Actually, the thread-system is running reliable, but after a longer runtime (3-5h), some sub-threads just die without a warning or an error. They just exit one after another - but again only with a time-range of 2-x hours. I have used jconsole to check this phenomenon, which threads are running and how they just simply disappear.

Furthermore, the main-thread is executing every second, but the sub-threads are mainly wait()ing and are not often used at all (since there are not so many tasks in the test environment).

The only reason I can think of is, that the JVM turns off the sub-threads since they are not often used enough?

I would be very thankfull for your help!

P.S. All threads are not defined as daemons and the main-thread just works fine!

edit

Thanks for your answers, but I actually use this loop.

public void addTask (Task in_task) throws InterruptedException {
        synchronized (tasks) {
              while (tasks.size() == MAXIMUM_NUMBER_OF_TASKS) {
                   tasks.wait();
              }
              tasks.offer(in_task);
              tasks.notifyAll();
        }
}

I use this loop, so that only some speciall amount of tasks will be executed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

温折酒 2024-11-02 07:52:47

Object.wait() 的文档说:

与单参数版本一样,中断和虚假唤醒是可能的,并且此方法应始终在循环中使用:

 synchronized (obj) {
     while (<condition does not hold>)
         obj.wait();
     ... // Perform action appropriate to condition
 }

也许您没有遵循此建议并得到了虚假唤醒或中断?

The documentation for Object.wait() says:

As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:

 synchronized (obj) {
     while (<condition does not hold>)
         obj.wait();
     ... // Perform action appropriate to condition
 }

Maybe you didn't follow this advice and got a spurious wakeup or interrupt?

把梦留给海 2024-11-02 07:52:47

您可以使用 java.util.concurrent.ThreadPoolExecutor。无论您是否能够修复此错误,这都可能是一个好主意。

Instead of writing your own multi-threaded task execution solution you could use java.util.concurrent.ThreadPoolExecutor. This would probably be a good idea no matter whether you are able to fix this bug or not.

渔村楼浪 2024-11-02 07:52:47

我建议使用Executors之一来管理您的任务。您在子线程之一中丢失可能的错误或异常的可能性较小,因此它应该可以帮助您调试程序。子线程中发生的任何异常都将存储在 Future 对象中,并在调用 Future#get() 时作为 ExecutionException 重新抛出。

List<Future<Void>> taskResults = new ArrayList<Future<Void>>();
ExecutorService es = Executors.newFixedThreadPool(NUMBER_OF_THREADS);

while(!finished){
  //say you wait (blocking) for a new task here
  Callable<Void> task = getNextTask();

  //put the task into the pool
  Future<Void> result = es.submit(task);
  taskResults.add(result);
}

//3 hours later, set `finished` to true

//at the end check that no exceptions were thrown
for(Future<Void> result : taskResults){
  try{
    result.get();
  }catch(ExecutionException e){
    //there was an error
    e.getCause().printStackTrace();
  }catch(InterruptedException e){
    //irrelevant
  }
}

一般来说,java.util.concurrent 中的内容可以帮助您编写更健壮的多线程应用程序,而不必求助于 Object#wait() 和其他并发原语(当然,除非你正在学习)。

I recommend using one of the Executors for managing your tasks. There are less chances that you will lose a possible error or exception in one of you sub-threads, so it should help you debug you program. Any exception that happens in a sub-thread will be stored inside the Future object and rethrown as an ExecutionException when you call Future#get().

List<Future<Void>> taskResults = new ArrayList<Future<Void>>();
ExecutorService es = Executors.newFixedThreadPool(NUMBER_OF_THREADS);

while(!finished){
  //say you wait (blocking) for a new task here
  Callable<Void> task = getNextTask();

  //put the task into the pool
  Future<Void> result = es.submit(task);
  taskResults.add(result);
}

//3 hours later, set `finished` to true

//at the end check that no exceptions were thrown
for(Future<Void> result : taskResults){
  try{
    result.get();
  }catch(ExecutionException e){
    //there was an error
    e.getCause().printStackTrace();
  }catch(InterruptedException e){
    //irrelevant
  }
}

In general, stuff in the java.util.concurrent helps you write much more robust multi-threaded applications, without having to resort to Object#wait() and other concurrency primitives (unless you are learning, of course).

鹤仙姿 2024-11-02 07:52:47

尝试在每个线程上设置一个未捕获的异常处理程序。
Thread 上有一个 setUncaughtExceptionHandler() 函数。实现 UncaughtExceptionHandler 接口并打印异常。

一般想法,但不要使用匿名类/方法:

thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
{
  public void uncaughtException(Thread t, Throwable e)
  {
    e.printStackTrace();
  }
}); 

Try setting an uncaught exception handler on each thread.
There is a setUncaughtExceptionHandler() function on the Thread. Implement the UncaughtExceptionHandler interface and print the exception.

General idea, but don't do it with anonymous classes/methods:

thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
{
  public void uncaughtException(Thread t, Throwable e)
  {
    e.printStackTrace();
  }
}); 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文