线程池

suaxi
2021-02-14 / 0 评论 / 50 阅读 / 正在检测是否收录...

线程池

线程池:三大方法7大参数4种拒绝策略

池化技术

事先准备好一些资源,要用的时候从池子中取,用完之后还回去

优点:

  • 降低资源的消耗
  • 提高响应速度
  • 方便管理


三大方法
package com.sw.pool;

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

/**
 * @Author suaxi
 * @Date 2021/2/14 21:23
 */
public class PoolTest {
    public static void main(String[] args) {
        //ExecutorService pool = Executors.newSingleThreadExecutor(); //单个线程
        //ExecutorService pool = Executors.newFixedThreadPool(10); //创建一个固定大小的线程池
        ExecutorService pool = Executors.newCachedThreadPool(); //线程池大小可弹性伸缩

        try {
            for (int i = 0; i < 50; i++) {
                pool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "--->Pool Test");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //线程池用完,程序结束,关闭线程池
            pool.shutdown();
        }
    }
}


七大参数
    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.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

池化技术-7大参数.png

图片来源:狂神说Java


手动创建一个线程池
package com.sw.pool;

import java.util.concurrent.*;

/**
 * @Author suaxi
 * @Date 2021/2/14 21:23
 * 4种拒绝策略:
 * AbortPolicy() 线程池满了,还有人进来,不处理这个人的请求,同时抛出异常
 * CallerRunsPolicy() 哪里来的请求,回到哪里去(请求对应的主方法)
 * DiscardPolicy() 队列满了,丢掉后来的请求,不抛出异常
 * DiscardOldestPolicy()  队列满了,尝试去和最早进行服务的窗口竞争,看那里的服务是否快要结束了,结束就进去提出请求,这种策略也不抛出异常
 */
public class ThreadPoolExecutorTest {
    public static void main(String[] args) {
        //自定义线程池
        ExecutorService pool = new ThreadPoolExecutor(
                2,
                5,
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardOldestPolicy());

        try {
            for (int i = 0; i < 50; i++) {
                pool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "--->Pool Test");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //线程池用完,程序结束,关闭线程池
            pool.shutdown();
        }
    }
}


4种拒绝策略

池化技术-4种拒绝策略.png

  • AbortPolicy() 线程池满了,还有人进来,不处理这个人的请求,同时抛出异常
  • CallerRunsPolicy() 哪里来的请求,回到哪里去(请求对应的主方法)
  • DiscardPolicy() 队列满了,丢掉后来的请求,不抛出异常
  • DiscardOldestPolicy() 队列满了,尝试去和最早进行服务的窗口竞争,看那里的服务是否快要结束了,结束就进去提出请求,这种策略也不抛出异常


小结

1、线程池不允许使用Executor创建(不安全),而是通过ThreadPoolExecutor这样的方式

2、如何定义线程池最大的大小?

(1) CPU密集型

根据cpu核数来设定

Runtime.getRuntime().availableProcessors();

(2) IO密集型

判断程序中十分耗IO的线程,一般设置为其两倍的大小

0

评论 (0)

取消