第六天:java多线程(线程池)

概述:线程池是一种可以复用线程的技术;

意义:

        线程是稀缺资源,它创建与销毁是相对偏重且耗资源的操作;线程池就是一个线程缓存,负责对线程进行统一分配、调优与监控。

优势:

        1、提高效率,创建好一定数量的线程放在池中等待,比需要时重新创建要快的多

        2、减少创建和销毁的次数

        3、提高响应速度

创建方式:

        Executors类(并发包)提供了4种创建线程池方法,这些方法最终都是通过配置ThreadPoolExecutor的不同参数,来达到不同的线程管理效果

newCacheTreadPool

        创建一个可以缓存的线程池,如果线程池长度超过处理需要,可以灵活回收空闲线程,没回收的话就新建线程

扫描二维码关注公众号,回复: 15054015 查看本文章
public static void main(String[] args)  {
    // 创建可缓存线程池
    ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
 
    for (int i = 0; i < 5; i++) {
        //创建任务
        Runnable runnable = new Runnable(){
            @Override
            public void run() {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName());
            }
        };
        newCachedThreadPool.execute(runnable);
    }
}

        线程池的最大核心线程为无限大,当执行第二个任务时第一个任务已经完成,则会复用执行第一个任务的线程;如果第一个线程任务还没有完成则会新建一个线程

newFixedThread

        创建一个定长的线程池,可控制最大并发数,超出的线程进行队列等待

public static void main(String[] args)  {
    // 创建定长线程池
    ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(2);
 
    for (int i = 0; i < 5; i++) {
        //创建任务
        Runnable runnable = new Runnable(){
            @Override
            public void run() {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName());
            }
        };
        // 将任务交给线程池管理
        newFixedThreadPool.execute(runnable);
    }
}

        创建指定长度的线程池,任务超出当前线程池执行线程数量则会一直等待,直到运行。

newScheduleThreadPool

        可以创建定长的、支持定时任务,周期任务执行。

public static void main(String[] args)  {
    // 创建支持定时线程池
    ScheduledExecutorService  newScheduledThreadPool = Executors.newScheduledThreadPool(2);
 
    for (int i = 0; i < 5; i++) {
        //创建任务
        Runnable runnable = new Runnable(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        };
        // 将任务交给线程池管理,延迟2秒后才开始执行线程池中的所有任务
        newScheduledThreadPool.schedule(runnable, 2, TimeUnit.SECONDS);
    }
}

        以下案例中延迟2秒后开始执行线程池中的所有任务

newSingleExecutor

        创建一个单线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行

public static void main(String[] args)  {
    // 创建单线程-线程池,任务依次执行
    ExecutorService   newScheduledThreadPool = Executors.newSingleThreadExecutor();
    for (int i = 0; i < 5; i++) {
        //创建任务
        Runnable runnable = new Runnable(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        };
        // 将任务交给线程池管理
        newScheduledThreadPool.execute(runnable);
    }
}

工作原理:

 ThreadPoolExecutor :

/**
     * 用给定的初始参数创建一个新的ThreadPoolExecutor。
     */
    public ThreadPoolExecutor(int corePoolSize,//线程池的核心线程数量
                              int maximumPoolSize,//线程池的最大线程数
                              long keepAliveTime,//当线程数大于核心线程数时,多余的空闲线程存活的最长时间
                              TimeUnit unit,//时间单位
                              BlockingQueue<Runnable> workQueue,//任务队列,用来储存等待执行任务的队列
                              ThreadFactory threadFactory,//线程工厂,用来创建线程,一般默认即可
                              RejectedExecutionHandler handler//拒绝策略,当提交的任务过多而不能及时处理时,我们可以定制策略来处理任务
                               ) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

四大策略:

new ThreadPoolExecutor.AbortPolicy():

        队列满了,直接丢弃,并抛出异常

new ThreadPoolExecutor.CallerRunsPolicy():

        队列满了,直接丢弃任务,不抛出异常

new ThreadPoolExecutor.DiscardPolicy():

        队列满了,丢弃等待最久未处理的任务,并加入到等待队列中

new ThreadPoolExecutor.DiscardOldestPolicy():

         队列满了,直接在主线程中运行,不再进入线程池

最大线程数目调优:

        CPU密集型:CPU集合,最大线程数就是几,可以保持CPU效率最高

        IO密集型:判断程序中十分耗IO的线程,大于它 (两倍)15个 就设30

猜你喜欢

转载自blog.csdn.net/qq_35056891/article/details/126567973