简体   繁体   English

主线程中的 run() 方法完成后我的程序不会停止

[英]My program will not stop after run() method in main thread finishes

I am using Java.我正在使用 Java。 The main thread sends data, while a worker thread listens to responses.主线程发送数据,而工作线程监听响应。 I also have Timer in case timeout occurs.我也有 Timer 以防发生超时。 In main(), I am calling run(), which can finish, according to the output.在main()中,我调用run(),可以完成,根据output。 Here is what it looks like:这是它的样子:

class Send {
    Worker w;

    run() {
        // w was initialized in constructor
        w.start();
        ....
        w.join();
    }

    main(args) {
        Send s = new Send();
        s.run();
    }
    private class Worker extend Thread {
        public void run() {
            ....
        }
    }
} 

In s.run(), every time I need to cancel the Timer or restart the Timer, I would do在 s.run() 中,每次我需要取消 Timer 或重新启动 Timer 时,我都会这样做

timer.cancel();
timer.purge();
timer = new Timer();
timer.schdule(...);

The TimerTask is simply calling a static method in Send to handle the timeout. TimerTask 只是在 Send 中调用 static 方法来处理超时。 So what did I do wrong to cause my program hanging after the main thread finishes?那么我做错了什么导致我的程序在主线程完成后挂起? Thank you.谢谢你。


EDIT: the out put of kill -3 process-id :编辑: kill -3 process-id的输出:

Full thread dump OpenJDK 64-Bit Server VM (19.0-b09 mixed mode):

"DestroyJavaVM" prio=10 tid=0x00007f9f20035000 nid=0x73f1 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Timer-10" prio=10 tid=0x0000000001a7d800 nid=0x740f in Object.wait() [0x00007f9f1e39c000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x000000075833fe78> (a java.util.TaskQueue)
    at java.lang.Object.wait(Object.java:502)
    at java.util.TimerThread.mainLoop(Timer.java:505)
    - locked <0x000000075833fe78> (a java.util.TaskQueue)
    at java.util.TimerThread.run(Timer.java:484)

"Low Memory Detector" daemon prio=10 tid=0x00007f9f20004800 nid=0x7402 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"CompilerThread1" daemon prio=10 tid=0x0000000001a70000 nid=0x7401 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"CompilerThread0" daemon prio=10 tid=0x00007f9f20001000 nid=0x7400 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=10 tid=0x0000000001a6e800 nid=0x73ff waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=10 tid=0x0000000001a49000 nid=0x73fe in Object.wait() [0x00007f9f1f3f2000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000007580b1310> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:133)
    - locked <0x00000007580b1310> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:149)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177)

"Reference Handler" daemon prio=10 tid=0x0000000001a47000 nid=0x73fd in Object.wait() [0x00007f9f1f4f3000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000007580b11e8> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:502)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
    - locked <0x00000007580b11e8> (a java.lang.ref.Reference$Lock)

"VM Thread" prio=10 tid=0x0000000001a40000 nid=0x73fc runnable 

"GC task thread#0 (ParallelGC)" prio=10 tid=0x00000000019d7000 nid=0x73f2 runnable 

"GC task thread#1 (ParallelGC)" prio=10 tid=0x00000000019d9000 nid=0x73f3 runnable 

"GC task thread#2 (ParallelGC)" prio=10 tid=0x00000000019da800 nid=0x73f4 runnable 

"GC task thread#3 (ParallelGC)" prio=10 tid=0x00000000019dc800 nid=0x73f5 runnable 

"GC task thread#4 (ParallelGC)" prio=10 tid=0x00000000019de800 nid=0x73f6 runnable 

"GC task thread#5 (ParallelGC)" prio=10 tid=0x00000000019e0000 nid=0x73f7 runnable 

"GC task thread#6 (ParallelGC)" prio=10 tid=0x00000000019e2000 nid=0x73f8 runnable 

"GC task thread#7 (ParallelGC)" prio=10 tid=0x00000000019e4000 nid=0x73f9 runnable 

"GC task thread#8 (ParallelGC)" prio=10 tid=0x00000000019e5800 nid=0x73fa runnable 

"GC task thread#9 (ParallelGC)" prio=10 tid=0x00000000019e7800 nid=0x73fb runnable 

"VM Periodic Task Thread" prio=10 tid=0x00007f9f20007800 nid=0x7403 waiting on condition 

JNI global references: 886

Heap
 PSYoungGen      total 150528K, used 7745K [0x00000007580b0000, 0x00000007628a0000, 0x0000000800000000)
  eden space 129088K, 6% used [0x00000007580b0000,0x00000007588405b8,0x000000075fec0000)
  from space 21440K, 0% used [0x00000007613b0000,0x00000007613b0000,0x00000007628a0000)
  to   space 21440K, 0% used [0x000000075fec0000,0x000000075fec0000,0x00000007613b0000)
 PSOldGen        total 343936K, used 0K [0x0000000608200000, 0x000000061d1e0000, 0x00000007580b0000)
  object space 343936K, 0% used [0x0000000608200000,0x0000000608200000,0x000000061d1e0000)
 PSPermGen       total 21248K, used 3130K [0x00000005fdc00000, 0x00000005ff0c0000, 0x0000000608200000)
  object space 21248K, 14% used [0x00000005fdc00000,0x00000005fdf0ea30,0x00000005ff0c0000)

A Java program will exit after the last thread finishes. Java 程序将在最后一个线程完成后退出。

To prevent that, mark the other threads as daemon threads.为防止这种情况,请将其他线程标记为守护线程。

Get a thread dump by running kill -3 <process id> .通过运行kill -3 <process id>获取线程转储。 This will tell you which threads are hanging around & preventing the java process from exiting.这将告诉您哪些线程正在挂起并阻止 java 进程退出。 Feel free to post (some of) the thread dump & folks can help you figure out what to do next.随意发布(一些)线程转储,人们可以帮助您确定下一步该做什么。

It looks like you are creating several Timer threads.看起来您正在创建多个 Timer 线程。 Check that all of them have exited properly, that is probably the problem.检查它们是否都已正确退出,这可能是问题所在。

If you check the Timer JavaDoc - http://download.oracle.com/javase/6/docs/api/java/util/Timer.html - you will notice the following note:如果您查看 Timer JavaDoc - http://download.oracle.com/javase/6/docs/api/java/util/Timer.html - 您会注意到以下注意事项:

By default, the task execution thread does not run as a daemon thread默认情况下,任务执行线程不作为守护线程运行

You can use a debugger (both Eclipse and NetBeans have excellent ones) to see which threads are still alive.您可以使用调试器(Eclipse 和 NetBeans 都有出色的调试器)来查看哪些线程仍然处于活动状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM