java:线程ID重用ID

时间:2016-11-11 06:55:46

标签: java multithreading

根据Thread.getId()的文件:

  

返回此Thread的标识符。线程ID是创建此线程时生成的正长数。线程ID是唯一的,并且在其生命周期内保持不变。 当线程终止时,可以重用此线程ID。 [强调添加]

但是,在什么情况下可以重用线程ID?查看source code for Thread.java,获取下一个线程ID的方法只增加一个静态long:

private static synchronized long nextThreadID() {
    return ++threadSeqNumber;
}

我没有看到这段代码将如何重用旧ID,除非通过重复使用它们只是意味着最终增加的long将循环回到之前的值(但这没有意义,因为长期意志在这样做之前变得消极 - 这打破了文档。

简而言之问题:重复使用线程ID的方式,以及重用它们的原因是什么?

3 个答案:

答案 0 :(得分:3)

JDK类可以有许多不同的实现。您查看了{em> Thread的实现,发现它永远不会重用线程ID;但是Javadoc只是说线程的ID 可能在它终止后被重用,也就是说,JDK实现可以重用已终止线程的线程ID。 / p>

答案 1 :(得分:2)

这是计划合同与实施之间差异的一个很好的例子。合同保证Thread.getId()在所有活动线程中都是唯一的,但是合同并不保证在线程终止时不能重用这些ID。这意味着无论当前的实现,您都必须在假设可以重用旧线程ID的情况下进行编程。

unspecified behavior的一个例子是,没有记录可以重复使用的确切案例。虽然未指明的行为可能会有问题,但它也是图书馆和语言开发人员避免过度指定他们并不意味着遵守的合同的必要工具。在这种情况下,合同本质上是避免承诺在流程的生命周期中确保唯一的线程ID,这简化了创建新线程必须花费的精力。

考虑合同是否承诺永远不会重用线程ID。 Java作者需要实现某种额外的机制来确保额外的合同。这将带来成本(作者方面的时间,记忆和/或认知开销),基本上,作者认为这些成本并不值得。

简而言之,您的问题的答案是"我们不知道"以及那是设计的。避免编写假定线程ID将全局唯一的代码,或者有一天代码可能会中断。

顺便说一句,有趣的是,规范确实保证ID是正面的,但Thread.nextThreadID()并没有强制执行。它可能根本不是一个实际的问题(你必须启动2 ^ 61个线程来解决这个问题,这将需要7300万年在一个线程每毫秒:)),但它&#39有趣的是,他们避免了有前途的独特性,但实际上并没有确保非负值。在使用当前实施方案达到重复ID之前,您已达到否定值。

答案 2 :(得分:1)

方法nextThreadId是私有的,所以当你想要考虑类的接口时,你甚至不应该看它。

线程id仅由方法Thread.getId()返回。这个方法 final,所以我可以创建自己的Thread子类,它具有不同的实现,并且可以重用线程ID。

javadoc仅说明每个实现和子类应遵循的约束。