Bob*_*Bob 54 java multithreading
我一直认为创建线程很昂贵.
我也知道你不能重新运行一个帖子.
我在Executors课堂上看到:
创建一个根据需要创建新线程的线程池,但在它们可用时将重用先前构造的线程.
注意'重用'这个词.
线程池如何"重用"线程?
Syn*_*r0r 50
我想我明白了什么让你感到困惑所以这里是我的答案:这个术语有点误导(显然,或者你不会特别强调'重用'这个问题):
线程池如何"重用"线程?
发生的事情是单个线程可用于处理多个任务(通常作为传递Runnable,但这取决于您的'执行者'框架:默认执行程序接受Runnable,但您可以编写自己的"执行程序"/线程池接受某些内容比Runnable[比如说,a CancellableRunnable] 更复杂.
现在在默认ExecutorService实现中,如果某个线程在仍在使用时以某种方式终止,它将自动替换为新线程,但这不是他们所讨论的"重用".在这种情况下没有"重用".
因此,它是真实的,你不能说start()在一个Java线程的两倍,但你可以通过尽可能多的Runnable,只要你想执行人和各Runnable的run()方法将被调用一次.
您可以传递30 Runnable到5个Java,Thread并且每个工作线程可能正在调用,例如,run()6次(实际上不保证您将执行正好6 Runnable个,Thread但这是一个细节).
在这个例子start()中将被调用6次.每个人这6 start()将调用仅一次的run()每个方法Thread:
来自Thread.start()Javadoc:
Run Code Online (Sandbox Code Playgroud)* Causes this thread to begin execution; the Java Virtual Machine * calls the <code>run</code> method of this thread.
但随后每个线程的内部run()方法Runnable必须离队,并在run()每一个方法Runnable将被调用.所以每个线程都可以处理几个Runnable.这就是他们通过"线程重用"所指的内容.
执行自己的线程池的一种方法是使用一个阻塞队列,在该队列中将runnables排入队列并拥有每个线程,一旦处理完run()a 的方法Runnable,将下一个Runnable(或块)出列并运行其run()方法,然后冲洗并重复.
我猜混乱的一部分(这是一个有点混乱)来自于一个事实,即Thread需要Runnable和在调用start()Runnable的run()方法被调用,而默认的线程池也需要Runnable.
Mik*_*els 14
该run线程的线程池的方法并不只包括运行单个任务.run线程池中线程的方法包含一个循环.它将任务从队列中拉出,执行任务(在完成时返回循环),然后获取下一个任务.在run不再需要该线程之前,该方法不会完成.
编辑添加:
这是ThreadPoolExecutor中内部类的run方法.Worker
696: /**
697: * Main run loop
698: */
699: public void run() {
700: try {
701: Runnable task = firstTask;
702: firstTask = null;
703: while (task != null || (task = getTask()) != null) {
704: runTask(task);
705: task = null; // unnecessary but can help GC
706: }
707: } finally {
708: workerDone(this);
709: }
710: }
Run Code Online (Sandbox Code Playgroud)