【线程池上篇】4种常用线程池介绍

一、线程池介绍

概念+使用原因:线程池就是提前创建好一些线程放在一起的集合,线程池的工作模式时拿到任务后在自己的池子里找看谁闲着,这个活就让谁去干,
多线程模式下,系统需要不断地启动和关闭新线程,这个过程不但消耗资源而在存在线程间过渡的不安全性。ExecuorService 是Java提供的用于管理线程池的类,主要作用是控制线程数量和重用线程

线程池的构成
一个线程池包括以下四个基本组成部分:
1、线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。

使用线程池的好处:
1、降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗。

2、提高响应速度:当任务到达时,可以不需要等待线程创建就能立即执行。

3、提高线程的可管理性:线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,监控和调优。

二、四种常用线程池

1、可缓存线程池(NewCachedThreadPool)

NewCachedThreadPool:可缓存线程池,先到池子里看一下,以前的可用就直接用,如果现有线程没有可用的,则创建一个新线程并添加到池中。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class NewCachedThreadPoolDemo {
    public static void main(String[] args) throws InterruptedException {
        //创建一个可缓存线程池
        ExecutorService cachedThreadPool=Executors.newCachedThreadPool();
        for(int i=0;i<10;i++){
            Thread.sleep(10);
        }
        cachedThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        });
    }
}

2、指定工作线程的线程池(NewFixedThreadPool)

NewFixedThreadPool:创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class NewFixedThreadPoolDemo {
    public static void main(String[] args) {
        ExecutorService fixedThreadPool=Executors.newFixedThreadPool(4);
        for(int i=0;i<10;i++){
            fixedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    try{
                        System.out.println(Thread.currentThread().getName());
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } ;
                }
            });
        }
    }

}

在这里插入图片描述
3、定时的线程池newScheduledThreadPool

newScheduledThreadPool:创建一个定时定长而且周期性的执行任务的线程池,

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class newScheduledThreadPoolDemo {
    public static void main(String[] args) {
        //创建一个定长线程池,
        ScheduledExecutorService scheduleThreadPool=Executors.newScheduledThreadPool(5);
        scheduleThreadPool.scheduleAtFixedRate(new Runnable() {
            public void run(){
                System.out.println("延迟1s后每三秒执行一次");
            }
        } ,1,3, TimeUnit.SECONDS);
    }
}

这中间每个都隔了三秒
在这里插入图片描述

4、单线程线程池(NewSingleThreadExecutor)

NewSingleThreadExecutor:创建一个单线程化的Executor,Executors.newSingleThreadExecutor()返回一个线程池(这个线程池只有一个线程) ,这个线程池可以在线程死后(或发生异常时)重新启动一个线程来替代原来的线程继续执行下去。它只会用唯一的工作线程来顺序执行任务。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class NewSingleThreadExecutorDemo {
    public static void main(String[] args) {
        //创建一个单线程版的线程池
        ExecutorService singleThreadExecutor=Executors.newSingleThreadExecutor();

        for(int i=0;i<10;i++){
            int index=i;
            singleThreadExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"打印的值是"+index);
                }
            });
        }
    }
}

可以看到打印的结果是顺序执行
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/chris__x/article/details/107331614