Executors创建线程池的方法——6种
public class ThreadPool1 {
public static void main(String[] args) {
//1.创建一个大小为5的线程池
ExecutorService threadPool= Executors.newFixedThreadPool(5);
//2.使用线程池执行任务一
for (int i=0;i<5;i++){
//给线程池添加任务
threadPool.submit(new Runnable() {
@Override
public void run() {
System.out.println("线程名"+Thread.currentThread().getName()+"在执行任务1");
}
});
}
//2.使用线程池执行任务二
for (int i=0;i<8;i++){
//给线程池添加任务
threadPool.submit(new Runnable() {
@Override
public void run() {
System.out.println("线程名"+Thread.currentThread().getName()+"在执行任务2");
}
});
}
}
}
public class ThreadPool3 {
public static void main(String[] args) {
//创建线程池
ExecutorService service= Executors.newCachedThreadPool();
//有50个任务
for(int i=0;i<50;i++){
int finalI = i;
service.submit(()->{
System.out.println(finalI +"线程名"+Thread.currentThread().getName());//线程名有多少个,CPU就创建了多少个线程
});
}
}
}
结果:
执行了两次:一次有18个线程,一次有19个线程;线程的数量由cpu根据任务量而定。
创建单个线程的线程池?为啥不直接创个线程?
public class ThreadPool4 {
public static void main(String[] args) {
ExecutorService service= Executors.newSingleThreadExecutor();
for (int i=0;i<5;i++){
int finalI = i;
service.submit(()->{
System.out.println(finalI +"线程名"+Thread.currentThread().getName());//CPU只创建了1个线程,名称始终一样
});
}
}
}
public class ThreadPool5 {
public static void main(String[] args) {
ScheduledExecutorService service= Executors.newSingleThreadScheduledExecutor();
System.out.println("添加任务:"+ LocalDateTime.now());
service.schedule(new Runnable() {
@Override
public void run() {
System.out.println("执行任务:"+LocalDateTime.now());
}
},3,TimeUnit.SECONDS);//推迟3秒执行任务
}
}
/**
* 创建执行定时任务的线程池
*/
public class ThreadPool6 {
public static void main(String[] args) {
ScheduledExecutorService service = Executors.newScheduledThreadPool(5);//5个线程
System.out.println("添加任务:" + LocalDateTime.now());
//once(service);
many(service);
}
/**
* 执行一次的定时任务
*/
public static void once(ScheduledExecutorService service) {
service.schedule(new Runnable() {
@Override
public void run() {
System.out.println("执行任务:"+ LocalDateTime.now());
}
},3, TimeUnit.SECONDS);//推迟3秒执行
}
}
执行一次的定时任务 的结果:
当执行多次的定时任务——scheduleWithFixedDelay
//2.推迟3秒执行;上一次任务结束2s后,下一个任务开始执行
service.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
System.out.println("执行任务:"+ LocalDateTime.now()+"线程名"+Thread.currentThread().getName());
try {
Thread.sleep(1000*2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},3,2,TimeUnit.SECONDS);//间隔时间成了4s;因为线程休眠了2s
当执行多次的定时任务——scheduleAtFixedRate
//1.推迟3秒执行;上一次任务开始2s后,下一个任务开始执行
service.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("执行任务:"+ LocalDateTime.now()+"线程名"+Thread.currentThread().getName());
try {
//1.间隔时间>执行时间;以间隔时间为准
Thread.sleep(100);
//2.执行时间>间隔时间;以执行时间为准
Thread.sleep(1000*3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},3,2,TimeUnit.SECONDS);
public class ThreadPool7 {
public static void main(String[] args) {
ExecutorService service= Executors.newWorkStealingPool();
for(int i=0;i<50;i++){
int finalI = i;
service.submit(()->{
System.out.println(finalI +"线程名"+Thread.currentThread().getName());//线程名有多少个,CPU就创建了多少个线程
});
}
//创建的为守护线程,JVM不会等待守护线程结束
while (!service.isTerminated()){
}
}
}
根据自身电脑配置决定创建的线程数目
ThreadPoolExecutor——7.手动创建线程池
public class ThreadPool9 {
public static void main(String[] args) {
//线程工厂
ThreadFactory factory=new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread thread=new Thread(r);
return thread;
}
};
//手动创建线程池
ThreadPoolExecutor threadPoolExecutor=new ThreadPoolExecutor(2, 4, 3, TimeUnit.SECONDS,
new LinkedBlockingDeque<>(2), factory,
//1.提示异常,拒绝执行多余的任务
// new ThreadPoolExecutor.AbortPolicy()
//2.忽略堵塞队列中最旧的任务
//new ThreadPoolExecutor.DiscardOldestPolicy()
//3.忽略最新的任务
//new ThreadPoolExecutor.DiscardPolicy()
//4.使用调用该线程池的线程来执行任务
//new ThreadPoolExecutor.CallerRunsPolicy()
//5.A自定义拒绝策略
new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.out.println("拒绝策略");
}
}
);
//任务
for (int i=0;i<7;i++){
int finalI=i;
threadPoolExecutor.submit(()->{
try {
Thread.sleep(finalI*100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"任务名"+finalI);
});
}
}
}
核心(最少)线程数
最大线程数
闲置可存活时间
描述(闲置可存活时间)的单位
任务队列
线程工厂
拒绝策略有5种:
//1.提示异常,拒绝执行多余的任务
// new ThreadPoolExecutor.AbortPolicy()
//2.忽略堵塞队列中最旧的任务
//new ThreadPoolExecutor.DiscardOldestPolicy()
//3.忽略最新的任务
//new ThreadPoolExecutor.DiscardPolicy()
//4.使用调用该线程池的线程来执行任务
//new ThreadPoolExecutor.CallerRunsPolicy()
//5.自定义拒绝策略
new RejectedExecutionHandler()