使用线程池的目的:避免频繁创建和销毁线程
红色的是核心线程。蓝色的是临时线程,下面的蓝色粗条,是队列。
当用户进来时,服务器会分配核心线程给用户使用。该线程一直存在,不会关闭,
并且,没人使用的时候也会创建。
当核心线程分配满了之后,再进来的用户会进入队列等待。
当队列满了之后,再来的用户,服务器会创建临时线程使用,临时线程有数量由设置决定。
并且当临时线程使用完毕后,可以设置规定时间内没有使用,就会销毁。
当临时线程满了之后,再来的用户会进入拒绝服务助手。
ThreadPoolExecutor类为线程池类
public class ThreadPool {
/**ThreadPoolExecutor(
* corePoolSize, 核心线程数
* maximumPoolSize,最大线程数=核心线程数+临时线程数
* keepAliveTime, 临时线程的等待时间的值
* unit,临时线程的等待时间的单位
* workQueue,阻塞队列
* handler)由于超出线程范围和队列容量而使执行被阻塞
* 时所使用的处理程序
*/
@Test
public void testThreadPoolExecutor(){
//创建核心线程5个,临时线程5个,临时线程等待时间
//为60秒,阻塞队列容量5,满时输出线程池已满的线程池
ExecutorService es = new ThreadPoolExecutor(
5,10, 60,TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(5),
new RejectedExecutionHandler(){
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.out.println("线程池已满.阻塞队列已满...");
}
});
//向线程池中添加Runnable或Callable实现类的对象
for(int i =0;i<16;i++){
System.out.println("==========="+i);
es.submit(new MyRunner());
}
//只能添加Runnable实现类的对象
//es.execute(command);
//关闭线程池:并不是立即关闭,线程池中的线程会继续处理,
//直到线程池中的所有线程都处理完毕才会关闭线程池。
//调用该方法后,不再接收新的。
es.shutdown();
}
class MyRunner implements Runnable{
public void run(){
System.out.println(Thread.currentThread().getId()+"线程被处理中");
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
使用场景
ThreadPoolExecutor创建时可以自行设定,也可以使用设定好的。。
public class ThreadPool {
/** newCachedThreadPool()源代码:
* ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>())
核心线程数:0
最大线程数:Integer.MAX_VALUE
60L, TimeUnit.SECONDS:临时线程等待的时间60S
new SynchronousQueue<Runnable>():阻塞队列(1个)
大池子小队列:
使用再高并发短请求的场景中。
优点:能够及时有效的处理高并发的场景,用户请求的响应时间比较短。
缺点:占用服务器的大量资源(cpu和内存),线程的频繁的创建和销毁,
如果请求都是长请求,可能会导致内存溢出。
*/
@Test
public void testCachedThreadPool(){
ExecutorService es = Executors.newCachedThreadPool();
System.out.println();
}
/**newFixedThreadPool(核心线程数/最大线程数)
* ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>())
核心线程数:用户指定的
最大线程数=核心线程数,没有临时线程。
小池子大队列
优点:能够缓解服务器的压力。
缺点:效应时间比较长。
*/
@Test
public void testFixedThreadPool(){
ExecutorService es = Executors.newFixedThreadPool(10);
System.out.println();
}
}