优快云话题挑战赛第2期
参赛话题:一起学Java
线程池ThreadPool(创建线程的第三种方式)
1、线程池的作用
主要用于创建和管理若干个线程的一种容器,当我们需要执行任务时,可以从池中取出
线程来执行,当执行完任务后,将线程返回到池中,避免频繁的去创建和销毁线程,从而
节省空间,提升系统性能
2、自定义线程池
ThreadPoolExecutor pool=
new ThreadPoolExecutor(
核心线程数,
最大线程数,
超时(空闲,活跃)时间,
超时的时间单位,
任务队列,
线程工厂,
拒绝策略);
拒绝策略类型:
* 1》AbortPolicy:拒绝执行新的任务,并抛出异常
* 2》CallerRunsPolicy:如果线程池没有关闭,不使用线程池中的线程
* 也不会加入到任务队列,而是让当前线程直接调用run()方法来执行任务,
* 如果线程池已关闭,则直接丢弃掉该任务不执行
* 3》DiscardOldestPolicy: 如果线程池没有关闭,将任务队列中存放最久的任务
* (队首元素)移除掉,并将新的任务加入到任务队列中,如果线程池已经关闭
* 则直接丢弃掉该任务不执行
* 4》DiscardPolicy:拒绝执行任务,但是不会抛异常
3、jdk自带线程
1》单线程线程池
ExecutorService es=Executors.newSingleThreadExecutor()
只有一个核心线程,不允许创建非核心线程;
等上一个任务执行完了,才能执行下一个任务
2》固定数量线程池
ExecutorService es=Executors.newFixedThreadPool(int n);
传入的参数既是核心线程又是最大线程,
也就是不允许创建非核心线程
3》可缓存线程池
ExecutorService es=Executors.newCachedThreadPool();
没有核心线程,所有线程均为非核心线程
有多少任务就会创建多少个线程
线程最大数量为integer.max_value,
所有非核心线程空闲时间超过60S就会被回收
4》周期性线程池
ExecutorService es=Executors.newScheduledThreadPool(int n);
自己指定核心线程数
线程最大数量为integer.max_value
超时时间为0
任务队列为延迟队列
4、线程池的常用方法
1》execute(Runnable r)
将任务对象交给线程池,线程池会自动取出空闲线程来执行任务,
没有空闲线程就将任务加入到任务队列中,队列满了就触发拒绝策略
2》shutdown()
安全关闭线程池
只有等到线程池中所有线程都执行完任务后才会关闭
如果还有未执行完任务,当前方法会阻塞
3》shutdownNow();
立即关闭线程
无论线程池中是否还有未执行完的额任务,都会立即关闭线程池
会导致线程池还有未执行完的任务,返回这些未执行的线程
周期性线程中的主要方法
1》schedule(Runnable r,long delay, TimeUnit unit)
延迟指定时间后来执行这个r任务
2>scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit);
每间隔period指定的时间后来执行一次任务
如果一个任务的执行时间超过了间隔时间,
那么在一个任务执行完成红立即执行下一个任务,
如果没有超过,那么就在指定间隔时间后执行下一个任务
3》scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnit unit);
执行周期性任务
在一个任务执行完成后,再间隔设置的时间后,
再来执行下一个任务
import java.util.Date;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;
import java.util.concurrent.TimeUnit;
/*
* 线程池
*/
public class ThreadDemo16 {
public static void main(String[] args) {
//自定义线程池
/**
* 参数解释:
* 1、corePoolSize:核心线程数
* 线程池创建出来时就需要创建的线程数,线程池中需要保证最小数量线程
* 2、maximumPoolSize:最大线程数
* 线程池中允许存在的最大线程数量
* 3、keepAliveTime:超时(空闲,活跃)时间
* 非核心线程在指定时间内没有接收到新的任务,就会被销毁,
* 如果调用了allowCoreThreadTimeOut()方法并且参数为true,
* 那么超过指定时间后,核心线程也会被销毁
* 4、TimeUnit:keepAliveTime超时的时间单位
* 5、workQueue:任务队列
* 需要线程池中的线程执行任务所存放的队列
* 6、threadFactory:线程工厂
* 负责创建线程池中的线程
* 7、RejectedExecutionHandler:拒绝策略
* 当线程池中所有线程都在执行任务,并且任务队列也是满负荷的情况下
* 又有新的任务需要线程池来执行,就会触发拒绝策略
*
* 拒绝策略类型:
* 1》AbortPolicy:拒绝执行新的任务,并抛出异常
* 2》CallerRunsPolicy:如果线程池没有关闭,不使用线程池中的线程
* 也不会加入到任务队列,而是让当前线程直接调用run()方法来执行任务,
* 如果线程池已关闭,则直接丢弃掉该任务不执行
* 3》DiscardOldestPolicy: 如果线程池没有关闭,将任务队列中存放最久的任务
* (队首元素)移除掉,并将新的任务加入到任务队列中,如果线程池已经关闭
* 则直接丢弃掉该任务不执行
* 4》DiscardPolicy:拒绝执行任务,但是不会抛异常
*/
// ThreadPoolExecutor pool=
// new ThreadPoolExecutor(
// 3,
// 3,
// 10,
// TimeUnit.SECONDS,
// new ArrayBlockingQueue<Runnable>(5),
// new ThreadFactory() {
//
// @Override
// public Thread newThread(Runnable r) {
// return new Thread(r);
// }
// },
//
// new AbortPolicy());
//
// //创建任务对象,并交给线程池执行
// //线程池会自动取出空闲线程来执行该任务
// pool.execute(new ThreadTask("A"));
// pool.execute(new ThreadTask("B"));
// pool.execute(new ThreadTask("C"));
// pool.execute(new ThreadTask("D"));
// pool.execute(new ThreadTask("E"));
// pool.execute(new ThreadTask("F"));
// pool.execute(new ThreadTask("G"));
System.out.println("_____________________________________________");
//系统提供的线程池
/**
* 1、创建单个线程的线程池
* 只有一个核心线程,不允许创建非核心线程;
* 等上一个任务执行完了,才能执行下一个任务
*
*/
// ExecutorService es=
// Executors.newSingleThreadExecutor();
/**
* 2、创建固定的数量线程的线程池
* 传入的参数既是核心线程又是最大线程,
* 也就是不允许创建非核心线程
*/
// es=
// Executors.newFixedThreadPool(5);
/**
* 3、创建可缓存线程池
* 没有核心线程,所有线程均为非核心线程
* 有多少任务就会创建多少个线程
* 线程最大数量为integer.max_value,
* 所有非核心线程空闲时间超过60S就会被回收
*/
//
// es=
// Executors.newCachedThreadPool();
//
// es.execute(new ThreadTask("A"));
// es.execute(new ThreadTask("B"));
// es.execute(new ThreadTask("C"));
// es.execute(new ThreadTask("D"));
// es.execute(new ThreadTask("E"));
// es.execute(new ThreadTask("F"));
/**
* 4、周期性线程池
* 自己指定核心线程数
* 线程最大数量为integer.max_value
* 超时时间为0
* 任务队列为延迟队列
*/
ScheduledExecutorService es=
Executors.newScheduledThreadPool(3);
/**
* 指定延迟多长时间之后来执行任务
*
*/
// es.schedule(new Runnable() {
//
// @Override
// public void run() {
// System.out.println(new Date());
// }
// }, 5, TimeUnit.SECONDS);
/**
* 2、执行周期性任务
* 参数解释
* 1》周期执行的任务
* 2》第一次执行任务的的延迟时间
* 3》两次任务执行时间的间隔时间
* 4》时间单位
*
* 如果一个任务的执行时间超过了间隔时间,
* 那么在一个任务执行完成红立即执行下一个任务,
* 如果没有超过,那么就在指定间隔时间后执行下一个任务
*/
System.out.println(new Date());
es.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println(new Date());
}
}, 3, 1, TimeUnit.SECONDS);
/**
* 3、执行周期性任务
* 在一个任务执行完成后,再间隔设置的时间后,
* 再来执行下一个任务
*/
// System.out.println(new Date());
// es.scheduleWithFixedDelay(new Runnable() {
//
// @Override
// public void run() {
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println(new Date());
// }
// }, 3, 1, TimeUnit.SECONDS);
//关闭线程池
/*
* 安全关闭线程池
* 只有等到线程池中所有线程都执行完任务后才会关闭
* 如果还有未执行完任务,当前方法会阻塞
*/
// es.shutdown();
/*
* 立即关闭线程
* 无论线程池中是否还有未执行完的额任务,都会立即关闭线程池
* 会导致线程池还有未执行完的任务,返回这些未执行的线程
*/
// pool.shutdownNow();
}
}
//线程池需要执行的任务
class ThreadTask implements Runnable{
private String name;
public ThreadTask(String name) {
this.name=name;
}
@Override
public void run() {
System.out.println(
Thread.currentThread().getName()+"线程正在执行"+name+"任务");
}
@Override
public String toString() {
return "名称为"+name+"任务";
}
}