<!-- flowchart 箭头图标 勿删 -->
<svg style="display: none;">
<path d="M5,0 0,2.5 5,5z" id="raphael-marker-block" stroke-linecap="round" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
</svg>
<h4><a id="_0"></a>几种线程池的创建和使用</h4>
<p>目录:</p>
<ul>
<li>1.newFixedThreadPool固定线程池</li>
<li>2.newSingleThreadExecutor一个线程的线程池</li>
<li>3.newCachedThreadPool缓存线程池</li>
<li>4.ThreadPoolExecutor</li>
<li>5.Future获取返回结果</li>
</ul>
<h3><a id="1newFixedThreadPool_8"></a>1.newFixedThreadPool固定线程池</h3>
<p>示例:</p>
<pre class="blockcode"><code>ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
</code></pre>
<p>源码:</p>
<pre class="blockcode"><code> /**
* Creates a thread pool that reuses a fixed number of threads
* operating off a shared unbounded queue. At any point, at most
* {@code nThreads} threads will be active processing tasks.
* If additional tasks are submitted when all threads are active,
* they will wait in the queue until a thread is available.
* If any thread terminates due to a failure during execution
* prior to shutdown, a new one will take its place if needed to
* execute subsequent tasks. The threads in the pool will exist
* until it is explicitly {@link ExecutorService#shutdown shutdown}.
*
* @param nThreads the number of threads in the pool
* @return the newly created thread pool
* @throws IllegalArgumentException if {@code nThreads <= 0}
*/
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
</code></pre>
<p>解读一下源码注释:</p>
<pre class="blockcode"><code>创建一个线程池,该线程池复用固定数量的线程去操作一个共享的无界队列;
在任何时刻,最多只有nThreads的线程是处于可处理任务的活跃状态。
当所有的线程都处于活跃状态(在处理任务),如果提交了额外的任务,它将会在队列中等待,直到有线程可用。
如果线程在执行期间由于失败而终止,如果需要的话,一个新的线程将会取代它执行后续任务。
线程池中的线程将会一直存在,直到显示的关闭。
</code></pre>
<p>这里需要注意,线程的数量是固定的,但是队列大小是无界的(Integer.MAX_VALUE足够大,大到可以任务无界。)</p>
<p>注意这里用的队列:LinkedBlockingQueue,默认队列大小Integer的最大值。</p>
<pre class="blockcode"><code> /**
* Creates a {@code LinkedBlockingQueue} with a capacity of
* {@link Integer#MAX_VALUE}.
*/
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
</code></pre>
<p>代码测试:</p>
<pre class="blockcode"><code>package com.java4all.test11;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* Author: yunqing
* Date: 2018/9/19
* Description:
*/
@RestController
@RequestMapping(value = "testThread")
public class TestThread {
/**固定大小的线程池*/
static ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
@RequestMapping(value = "parse",method = RequestMethod.GET)
public String parse(){
Future<?> submit = fixedThreadPool.submit(() -> {
System.out.println("线程名称:" + Thread.currentThread().getName());
});
return null;
}
}
</code></pre>
<p>我们设定固定大小为4的线程池,然后用20个并发请求:</p>
<pre class="blockcode"><code>线程名称:pool-1-thread-1
线程名称:pool-1-thread-3
线程名称:pool-1-thread-4
线程名称:pool-1-thread-1
线程名称:pool-1-thread-3
线程名称:pool-1-thread-4
线程名称:pool-1-thread-4
线程名称:pool-1-thread-3
线程名称:pool-1-thread-4
线程名称:pool-1-thread-1
线程名称:pool-1-thread-1
线程名称:pool-1-thread-4
线程名称:pool-1-thread-1
线程名称:pool-1-thread-3
线程名称:pool-1-thread-4
线程名称:pool-1-thread-1
线程名称:pool-1-thread-3
线程名称:pool-1-thread-2
线程名称:pool-1-thread-2
线程名称:pool-1-thread-1
</code></pre>
<p>由是于队列无界,200 000个也是可以的,但是处理复杂任务时,无界队列可能会让内存爆掉。</p>
<h3><a id="2newSingleThreadExecutor_122"></a>2.newSingleThreadExecutor单线程</h3>
<p>示例:</p>
<pre class="blockcode"><code>static ExecutorService service = Executors.newSingleThreadExecutor();
</code></pre>
<p>源码:</p>
<pre class="blockcode"><code> /**
* Creates an Executor that uses a single worker thread operating
* off an unbounded queue. (Note however that if this single
* thread terminates due to a failure during execution prior to
* shutdown, a new one will take its place |
|