其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。
为什么要用线程池: 合理利用线程池能够带来三个好处
1.降低资源消耗。减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
2.提高响应速度
3.提高线程的可管理性 线程池的核心思想:线程复用。同一个线程可以被重复使用。
线程池在Java中的代表: ExecutorService
创建线程池的API: java.util.concurrent.Executors类下:
public static ExecutorService newFixedThreadPool(int nThreads)`:返回线程池对象。(创建的是有界线程池,也就是 池 中的线程个数可以指定最大数量)
往线程池中创建线程的API:
1.public Future> submit(Runnable task)
2.
小结: 线程池启动后是不会死亡的,因为后续还要重复使用的。
public class ThreadPoolsDemo01 {
public static void main(String[] args) {
// 1.新建一个只能存储3个线程的线程池。
ExecutorService pools = Executors.newFixedThreadPool(3);
// 2.public Future> submit(Runnable task)
Runnable target = new MyRunable();
// 往线程池中创建线程并加入!而且会自动启动!!
pools.submit(target);
pools.submit(target);
pools.submit(target);
// 加入第4个线程!会复用之前3个线程中的某一个线程!
pools.submit(target);
// 手工关闭线程池!!
// pools.shutdownNow(); // 立即关闭线程池,不管是否执行完毕!
pools.shutdown(); // 关闭线程池,等执行完毕才会执行关闭!
}
}
class MyRunable implements Runnable{
@Override
public void run() {
for(int i = 0 ; i < 3 ; i++ ){
System.out.println(Thread.currentThread().getName()+" => "+ i);
}
}
}
线程池在Java中的代表: ExecutorService
创建线程池的API: java.util.concurrent.Executors类下:
public static ExecutorService newFixedThreadPool(int nThreads)`:返回线程池对象。(创建的是有界线程池,也就是池中的线程个数可以指定最大数量)
往线程池中创建线程的API:
1.public Future> submit(Runnable task)
2.
分析:Callable接口创建线程对象是可以返回线程执行的结果的。
需求:用线程池计算出 1-20 以及 1-100的和。
总结: 以后创建线程建议大家用线程池做!
public class ThreadPoolsDemo02 {
public static void main(String[] args) throws Exception {
// 1.新建一个只能存储3个线程的线程池。
ExecutorService pools = Executors.newFixedThreadPool(3);
// 往线程池中加入线程任务对象Callable对象,然后会自动创建线程并启动!
// 返回一个未来任务对象给我们去获取线程执行的结果!
Future task1 = pools.submit(new MyCallable(20));
Future task2 = pools.submit(new MyCallable(100));
System.out.println(task1.get());
System.out.println(task2.get());
}
}
// 线程任务
class MyCallable implements Callable{
private int n ;
public MyCallable(int n){
this.n = n;
}
@Override
public String call() throws Exception {
int sum = 0 ;
for(int i = 1 ; i <= n ; i++ ){
sum += i;
System.out.println(Thread.currentThread().getName()+"输出:"+i);
}
return Thread.currentThread().getName()+"返回和是:"+sum;
}
}