JUC编程—线程池

JUC并发编程—线程池学习

好处:

1、降低资源的消耗;2、提高相应的速度;3、方便管理

1、线程池创建的三大方法

package com.zkw.JUC并发编程.线程池;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
// Executors 工具类、3大方法
public class Demo01 {
    
    
    public static void main(String[] args) {
    
    
        //ExecutorService threadPool = Executors.newSingleThreadExecutor();// 单个线程
        // ExecutorService threadPool = Executors.newFixedThreadPool(5);// 创建一个固定大小的线程池
        ExecutorService threadPool = Executors.newCachedThreadPool();// 创建一个 可伸缩的,遇强则强的线程池

        try {
    
    
            for (int i = 0; i < 100; i++) {
    
    
                // 使用了线程池之后,使用线程池来创建线程
                threadPool.execute(()->{
    
    
                    System.out.println(Thread.currentThread().getName()+" ok");
                });
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            // 线程池用完,程序结束,关闭线程池
            threadPool.shutdown();
        }
    }
}

2、7大参数

源码分析

  public static ExecutorService newSingleThreadExecutor() {
    
    
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

   public static ExecutorService newFixedThreadPool(int nThreads) {
    
    
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

 public static ExecutorService newCachedThreadPool() {
    
    
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,//约为20亿
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

//本质 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;
    }
package com.zkw.JUC并发编程.线程池;

import java.util.concurrent.*;

/**
 * 报出的异常:java.util.concurrent.RejectedExecutionException
 * 1、new ThreadPoolExecutor.AbortPolicy() //满了,还有人又进来,不处理,抛出异常
 * 2、new ThreadPoolExecutor.CallerRunsPolicy() //满了,还有人来,哪里来的去哪里
 * 3、new ThreadPoolExecutor.DiscardPolicy() //队列满了,还有要进的,不会抛出异常,会把任务丢掉
 * 4、new ThreadPoolExecutor.DiscardOldestPolicy() //队列满了,还有要进的,丢弃队列最前面的,然后重新提交被拒绝的
 */
public class Demo01 {
    
    
    public static void main(String[] args) {
    
    
         ExecutorService threadPool = new ThreadPoolExecutor(
                 2,
                 5,
                 3,
                 TimeUnit.SECONDS,
                 new LinkedBlockingDeque<>(3),
                 Executors.defaultThreadFactory(),
                 new ThreadPoolExecutor.AbortPolicy()
         );
        try {
    
    
            for (int i =1; i <= 9; i++) {
    
    
                threadPool.execute(()->{
    
    
                    //拒绝策略被执行的条件是,队列和线程池全满的时候
                    //加一个延时就是为了让里边的线程先在里边等着,这样才更容易看出拒绝策略被执行过
                    try {
    
    
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+" ok");
                });
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            threadPool.shutdown();
        }
    }
}

3、四中策略

  • 报出的异常:java.util.concurrent.RejectedExecutionException
  • 1、new ThreadPoolExecutor.AbortPolicy() 满了,还有人又进来,不处理,抛出异常
  • 2、new ThreadPoolExecutor.CallerRunsPolicy() 满了,还有人来,哪里来的去哪里
  • 3、new ThreadPoolExecutor.DiscardPolicy() 队列满了,还有要进的,不会抛出异常,会把任务丢掉
  • 4、new ThreadPoolExecutor.DiscardOldestPolicy() 队列满了,还有要进的,丢弃队列最前面的,然后重新提交被拒绝的

小结拓展

了解IO密集型、CPU密集型

池的大小到底该如何定义?

Runtime.getRuntime().availableProcessors() 获取电脑的CPU是几核的

1、CPU密集型,几核,就是几,可以保持CPU的效率最高!

2、IO密集型, 最大线程数 = 2* 判断程序中十分耗IO的线程

猜你喜欢

转载自blog.csdn.net/fgets__/article/details/120781627