我想我明白了什么是模糊化你,所以这里是我更长的答案:术语是一个有点误导(显然,或者你不会问这个问题,特别强调“重用”):
线程池如何重用线程?
发生的是,单个线程可以用于处理多个任务(通常作为Runnable传递,但这取决于你的’executor’框架:默认执行器接受Runnable,但你可以编写自己的“executor”/ thread-pool接受比Runnable更复杂的东西[比如说,CancellableRunnable])。
现在在默认ExecutorService实现中,如果一个线程以某种方式终止而仍在使用,它会自动替换为一个新的线程,但这不是他们正在谈论的“重用”。在这种情况下没有“重用”。
所以这是真的,你不能调用start()在一个Java线程两次,但你可以传递尽可能多的Runnable你想要的执行器和每个Runnable的run()方法将被调用一次。
您可以将30个Runnable传递给5个Java线程,每个工作线程可能正在调用,例如run()6次(实际上,不能保证每个线程都执行6个Runnable,但这是一个细节)。
在这个例子中,start()将被调用6次。每一个这6个start()将调用每个线程的run()方法一次:
从Thread.start()Javadoc:
06000
然后在每个线程的run()方法内,Runnable将被出队,每个Runnable的run()方法将被调用。所以每个线程都可以处理几个Runnable。这就是他们所说的“线程重用”。
做一个自己的线程池的一种方法是使用一个阻塞队列,在队列中加入队列并拥有每个线程,一旦完成对Runnable的run()方法的处理,则将下一个Runnable(或块)其run()方法,然后冲洗并重复。
我想部分的困惑(和有点混乱)来自事实,一个线程采取Runnable和调用start()Runnable的run()方法被调用,而默认线程池也采取Runnable。