在线程终止上调用方法

时间:2009-02-17 15:18:10

标签: java multithreading

我正在编写一个java程序,它跟踪在程序中创建的线程,然后在每个Thread终止时执行一些工作。

我在javadoc中没有看到任何'线程终止挂钩'。

目前,我能想到实现我的要求的唯一方法是保持线程对象并以重复的间隔查询其“状态”。

有没有更好的方法呢?

编辑: 我无法以任何方式包装runnable或修改runnable。 我的代码使用运行时检测,只是检测到创建了一个线程并获取了对Thread对象的引用。 此时runnable已经在运行。

8 个答案:

答案 0 :(得分:6)

您可以使用join() method

修改

如果在线程未终止之前不能阻止主线程,则可以创建一个子主线程,它将调用线程,然后使用join()方法等待它们。< / p>

答案 1 :(得分:3)

我看到了四种可能的方法。

  1. 使用您自己的Thread子类 重写run()方法。添加一个 最后阻止线程 终止。
  2. 使用Runnable 类似的装饰,也许就像一个 包装在提供的周围 Runnable接口。这个的变体是 子类Thread以便申请 施工时的这个包装。
  3. 创建第二个线程以加入() 真正的线程,从而检测它 终止。
  4. 使用检测重写上面的Thread.run()方法。

答案 2 :(得分:2)

java.lang.Threadsun.misc.VM的(sun 1.5)源代码中,只有一个名为threadStatus的线程中有一个字段。它是private int,其值映射到枚举java.lang.Thread.State。我没有验证这一点,也没有确定它发生的速度有多快,但是当一个线程最终终止时,这个值将被设置为java.lang.Thread.State.TERMINATED

通过这个相对简单的检测条件,我认为当字段设置为特定目标值时,在threadStatus上注入字段拦截器来触发事件是相当简单的。

答案 3 :(得分:1)

您可以为Runnable编写一个装饰器,它会调用终止钩子并在创建线程时将线程代码包装在其中。

答案 4 :(得分:1)

如果为每个run方法添加了try / finally块,则每个线程完成时都会执行内部代码。让线程负责自己的清理。

答案 5 :(得分:1)

如果您需要将代码注入第三方编译代码,AspectJ可以帮助您完成此操作,但显然它不适用于标准Java类库。

看起来这里有关于这样做的白皮书,但不知道它是否实用。我想你必须付钱。

http://portal.acm.org/citation.cfm?doid=1411732.1411754

你可以下载OpenJDK,自己设置钩子,编译一个自定义的JRE并随你的应用程序发送:)

答案 6 :(得分:0)

正如你所说,没有线程终止挂钩。你必须自己编码;在Runnables的run()方法结束时在控制器上调用一些方法(AFAIK子类化Thread被认为是不好的做法,你应该实现Runnable并创建一个以Runnable为目标的Thread。)

您还可以实现UncaughtExceptionHandler来了解线程是否因异常而异常终止,在这种情况下,您的控制器方法将不会被调用。

答案 7 :(得分:0)

如果你在java 1.5上运行,你可以使用java.lang.instrument和jvm的-javaagent选项来实现。

重新定义应该调用代码的线程对象上的run方法。您似乎已经使用了仪器,因此它应该可用。因为它修改了运行时字节码你应该没问题

那就是说,很难提供一个更具体和详细的​​答案,你的问题至少缺少jvm版本和使用的主要框架(想想spring-aop,jboss-aop,jvm等等)