Java多线程笔记3

时间:2022-03-01 17:29:49

*****线程池*****
创建线程的方式-推荐使用线程池来创建线程

线程池的核心两大接口
ExecutorService:普通线程池
-void execute(Runnable command);
-<T> Future<T> submit(Callable<T> task || Runnable);

ScheduledExecutorService:定时线程池

ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
  long initialDelay,
  long period,
  TimeUnit unit);

线程池的一个核心类:

ThreadPoolExecutor:ExecutorService的子类

ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)

线程池工作流程
当一个任务提交给线程池时,
1.首先判断核心池的线程数量是否达到corePoolSize,若未达到,线程池创建新的线程执行任务并将其置入核心池中。否则,判断核心池是否有空闲线程,若有,分配任务执行,否则进入步骤2.

2.判断阻塞队列是否已满,若未满,将任务置入阻塞队列中等待调度。否则,进入步骤3.

3.判断当前线程池中线程数量有没有达到线程池的最大数量(maximumPoolSize),若没有,创建新的线程执行任务并将其置入线程池中,否则,进入步骤4.

4.调用相应的拒绝策略打回任务(有四种拒绝策略,默认为抛出异常给用户AbortPolicy)

四种策略分别为:
1)AbortPolicy:直接抛出异常(默认采用此策略)
2)CallerRunsPolicy:只用调用者所在线程来运行任务
3)DiscardOldestPolicy:丢弃队列里最近的一个任务,执行此任务
4)DiscardPolicy:不处理,丢弃掉

BlockingQueue阻塞队列可以有以下几个选择:
1)ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按FIFO原则对元素进行排序
2)LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO排序元素,吞吐量一般高于ArrayBlockQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列
3)SynchronizedQueue:一个不存储元素的队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常高于LinkedBlockQueue,静态工厂方法Executors.newCachedThreadPool是用来这个队列
4)PriorityBlockingQueue:一个具有优先级的无限阻塞队列