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

时间:2011-06-28 19:52:31

标签: java multithreading timer

我正在使用Java。主线程发送数据,而工作线程侦听响应。如果发生超时,我也有Timer。在main()中,我根据输出调用run(),它可以完成。这是它的样子:

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() {
            ....
        }
    }
} 

在s.run()中,每次我需要取消定时器或重新启动定时器时,我都会这样做

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

TimerTask只是在Send中调用静态方法来处理超时。 那么我做错了什么导致我的程序在主线程完成后挂起? 谢谢。


编辑: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)

3 个答案:

答案 0 :(得分:3)

Java程序将在最后一个线程完成后退出。

为防止这种情况,请将其他线程标记为守护程序线程。

答案 1 :(得分:0)

通过运行kill -3 <process id>获取线程转储。这将告诉你哪些线程正在徘徊和阻止java进程退出。随意发布(部分)线程转储&amp;人们可以帮助你弄清楚下一步该做什么。

答案 2 :(得分:0)

看起来你正在创建几个Timer线程。检查它们是否已正确退出,这可能是问题所在。

如果您查看Timer JavaDoc - http://download.oracle.com/javase/6/docs/api/java/util/Timer.html - 您会注意到以下注释:

  

默认情况下,任务执行线程不作为守护程序线程运行

您可以使用调试器(Eclipse和NetBeans都有很好的调试器)来查看哪些线程仍然存在。