关于线程池这个东西,之前一直在了解层面,一直没有真正去了解,花一个小时搞一搞线程池?(未完待更新)
1、创建线程三种方法
既然需要了解线程池,那必然先搞一下线程创建的三种方法
1-1、继承Thread
// 1、继承Thread,重写run方法
public class first extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
Thread taskA = new first();
Thread taskB = new first();
taskA.start();
taskB.start();
}
}
result:
Thread-0
Thread-1
Process finished with exit code 0
1-2、实现Runnable接口
// 2、实现Runnable接口重写run方法,通过Thread来执行
public class second implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
Thread taskA = new Thread(new second());
Thread taskB = new Thread(new second());
taskA.start();
taskB.start();
}
}
1-3、实现Callable接口
// 3、实现callable(与前两种不同的是它可以通过FutureTask返回结果)
public class thrid implements Callable {
@Override
public String call() throws Exception {
String name = Thread.currentThread().getName();
return name + "执行完成";
}
public static void main(String[] args) {
FutureTask future = new FutureTask(new thrid());
new Thread(future).start();
try{
System.out.println(future.get());
}catch (Exception e) {
e.printStackTrace();
}finally {
// code
}
}
}
2、创建线程池
创建线程池有以下几种好处:
1、降低资源消耗,重复使用线程,避免线程重新创建
2、提高响应速度,一般核心线程存在的话能够避免线程等待时间
3、提高线程管理,可对线程进行监控
// 创建线程自定义线程工厂
public class CustomThread implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
// System.out.println(thread.getName());
return thread;
}
}
// 重写线程方法
public class Task extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
//主函数
public class ThreadPool {
public static void main(String[] args) {
Task taskA = new Task();
Task taskB = new Task();
Thread taskC = new Thread();
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(1,5,10,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(),
new CustomThread(),
new ThreadPoolExecutor.AbortPolicy());
threadPool.execute(taskA);
threadPool.execute(taskB);
threadPool.execute(taskC);
threadPool.shutdown();
}
}
一般情况下建议使用ThreadPoolExecutor创建线程池
字段 | 含义 |
---|---|
corePoolSize | 核心线程池 |
maximumPoolSize | 最大线程数 |
keepAliveTime | 空闲线程存活时间 |
unit | 上个字段单位 |
workQueue | 任务队列 |
threadFactory | 线程工厂(可自定义线程) |
handler | 任务拒绝策略(默认AbortPolicy抛出异常) |
理论上来说非核心线程池数=最大线程池-核心线程池,当非核心线程空闲下来,keepAliveTime时间后会销毁该线程。
线程决绝四种情况
1、线程池中线程已满
2、无法进行线程池扩容
3、无空闲线程
4、任务队列已满
其中FixedThreadPool、SingleThreadExecutor和CachedThreadPool三种线程池创建有风险不建议使用。