自定义线程池
ThreadPoolExecutor的构造方法:
public ThreadPoolExecutor(
int corePoolSize, 核心线程数
int maximumPoolSize, 最大线程数
Long keepAliveTime, 临时线程空闲时最大的存活时间
TimeUnit unit, 存活时间的单位
BlockingQueue workQueue, 线程池使用的缓冲队列
ThreadFactory threadFactory, 线程工厂 一般使用默认
RejectedExecutionHandler handler 拒绝策略
)
缓冲队列
ArrayBlockingQueue bounded(有界) 加锁 arrayList
LinkedBlockingQueue optionally-bounded 加锁 linkedList
SynchronousQueue bounded 加锁 无
阻塞队列方法
public void put(E e)将指定的元素插入此队列的尾部,如果该队列已满,则等待可用的空间。
public E take() 获取并移除此队列的头部,在元素变得可用之前一直等待(如果有必要)。
Executors类
创建线程池对象的工厂方法,使用此类可以创建线程池对象。
static ExecutorService newFixedThreadPool(int nThreads) 创建一个可重用固定线程数的线程池。
static ExecutorService newCachedThreadPool() 创建一个可根据需要创建新线程的线程池
static ExecutorService newSingleThreadExecutor() 创建一个使用单个 worker 线程的 Executor
static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
线程池对象的方法:
Future<?> submit(Runnable task) 提交线程执行的任务,方法将返回null,因为run()(方法没有返回值。
<T>Future<T>submit(Callable<T> task)提交线程执行的任务,返回Future接口对象。 配合Callable接口 Callable有返回值,future.get()即可拿到返回值
void shutdown() 关闭线程池,但是要等所有线程都完成任务后再关闭,但是不接收新任务。
拒绝策略:
1. ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常;也是默认的处理方式。
2. ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常。
3. ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
4. ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
package com.doit.demo05;
import java.util.Scanner;
import java.util.concurrent.*;
/*
自定义线程池
一秒创建一个线程,核心线程2,最大3,临时存活时间60秒,定义了一个存储5个线程的缓冲队列,线程工厂与拒绝策略使用了默认
*/
public class Test01 {
private static boolean flag = true;
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) { //如果控制台打印语句就获取
String next = sc.next();
if (next.equals("stop")){ //如果输入stop,线程任务停止
flag = false;
break;
}
}
}
}).start();
//创建线程池对象
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
2,
3,
60,
TimeUnit.SECONDS,//秒
new ArrayBlockingQueue<>(5) //缓冲队列
);
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
poolExecutor.execute(new MyRunnable(i+1+""));
}
}
static class MyRunnable implements Runnable{
private String name;
public MyRunnable(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行任务"+name);
while (flag){
/*死循环,线程1,2执行不完,多余线程进入阻塞队列,与临时线程,
如果不是死循环,线程秒结束,多余的线程也可以被执行*/
}
}
}
}
4878

被折叠的 条评论
为什么被折叠?



