欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

简单易懂-线程池

程序员文章站 2023-12-23 13:55:22
...
为什么要线程池

频繁的创建和销毁线程会降低系统效率,寻求一种线程复用的方式,那么可以使用缓存的策略,也就是使用线程池。简单说就是线程复用,提高效率,节约资源。

线程池是怎样的

线程池的核心类:ThreadPoolExecutor
ThreadPoolExecutor、AbstractExecutorService、ExecutorService和Executor
Executor:一个顶层接口,在它里面只声明了一个方法execute(Runnable),返回值为void,参数为Runnable类型,从字面意思可以理解,就是用来执行传进去的任务的;
ExecutorService接口:继承了Executor接口,并声明了一些方法:submit、invokeAll、invokeAny以及shutDown等;
抽象类AbstractExecutorService:实现了ExecutorService接口,基本实现了ExecutorService中声明的所有方法;
ThreadPoolExecutor: 继承了类AbstractExecutorService。
ThreadPoolExecutor的主要方法:

execute() //可以向线程池提交一个任务,交由线程池去执行。
submit() //用来向线程池提交任务的,但是它和execute()方法不同,它能够返回任务执行的结果
shutdown()
shutdownNow()// shutdown()和shutdownNow()是用来关闭线程池的。

ThreadPoolExecutor类中重要的成员变量:

private volatile long  keepAliveTime;    //线程存活时间   
private volatile boolean allowCoreThreadTimeOut;//是否允许为核心线程设置存活时间
private volatile int   corePoolSize;     //核心池的大小(即线程池中的线程数目大于这个参数时,提交的任务会被放进任务缓存队列)
private volatile int   maximumPoolSize;   //线程池最大能容忍的线程数
 
private volatile int   poolSize;       //线程池中当前的线程数
private volatile int   largestPoolSize; //记录线程池中曾经有过的最大线程数目,跟线程池的容量没有任何关系。

线程池的使用

import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
public class ThreadTest 
{
	public static void main(String[] args) 
	{
		//ExecutorService threadPool = Executors.newFixedThreadPool(10);一般用这种方式来创建线程池,下面的创建方式有比较好用的方法。
		ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS,//最大承受的线程数为10,下面队列的长度为6,如果创建的线程大于16就会发生错误,因为所有的线程都存活着,超容了。
		// public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue);
        new ArrayBlockingQueue<Runnable>(6));//当线程数大于corePoolSize时进入等待的队列
		for(int i = 0;i<16;i++){
			MyThread myThread1 = new MyThread(i);
			threadPool.execute(myThread1);
			System.out.println("线程池中线程数目:"+threadPool.getPoolSize()+",队列中等待执行的任务数目:"+
            threadPool.getQueue().size());
		}
		threadPool.shutdown();
	}
}

class MyThread implements Runnable
{
	private int taskNum;
	public MyThread(int num){
		this.taskNum = num;
	}
	@Override
	public void run(){
		System.out.println("正在执行task:"+taskNum);
		try{
			Thread.currentThread().sleep(2000);
		}catch(InterruptedException e){
			e.printStackTrace();
		}
		System.out.println("task"+taskNum+" 执行完毕");
	}
}

结果

---------- java运行 ----------
线程池中线程数目:1,队列中等待执行的任务数目:0
正在执行task:0
线程池中线程数目:2,队列中等待执行的任务数目:0
正在执行task:1
线程池中线程数目:3,队列中等待执行的任务数目:0
正在执行task:2
线程池中线程数目:4,队列中等待执行的任务数目:0
正在执行task:3
线程池中线程数目:5,队列中等待执行的任务数目:0
线程池中线程数目:5,队列中等待执行的任务数目:1
线程池中线程数目:5,队列中等待执行的任务数目:2
线程池中线程数目:5,队列中等待执行的任务数目:3
线程池中线程数目:5,队列中等待执行的任务数目:4
线程池中线程数目:5,队列中等待执行的任务数目:5
线程池中线程数目:5,队列中等待执行的任务数目:6
正在执行task:4
线程池中线程数目:6,队列中等待执行的任务数目:6
正在执行task:11
线程池中线程数目:7,队列中等待执行的任务数目:6
正在执行task:12
线程池中线程数目:8,队列中等待执行的任务数目:6
正在执行task:13
线程池中线程数目:9,队列中等待执行的任务数目:6
正在执行task:14
线程池中线程数目:10,队列中等待执行的任务数目:6
正在执行task:15
task1 执行完毕
task0 执行完毕
正在执行task:5
task2 执行完毕
task3 执行完毕
正在执行task:6
task4 执行完毕
正在执行task:7
正在执行task:8
正在执行task:9
task11 执行完毕
正在执行task:10
task12 执行完毕
task13 执行完毕
task14 执行完毕
task15 执行完毕
task8 执行完毕
task10 执行完毕
task6 执行完毕
task9 执行完毕
task5 执行完毕
task7 执行完毕

输出完成 (耗时 4) - 正常终止
相关标签: 线城池

上一篇:

下一篇: