按我的理解,假设我不断给线程池提交新的同样的Runnable,线程池会复用已经运行完但没销毁的线程,来减少创建线程的开销。
但是,如果我们多次调用线程的start()方法,程序会崩溃的,而且Thread类也没有类似SetRunnable之类的方法,那么请问线程池是怎样做到的呢?
另外,当需要重复开启同样的线程时,最佳实践是什么?
谢谢!
按我的理解,假设我不断给线程池提交新的同样的Runnable,线程池会复用已经运行完但没销毁的线程,来减少创建线程的开销。
但是,如果我们多次调用线程的start()方法,程序会崩溃的,而且Thread类也没有类似SetRunnable之类的方法,那么请问线程池是怎样做到的呢?
另外,当需要重复开启同样的线程时,最佳实践是什么?
谢谢!
一个最简单的
class InnerThread extends Thread {
private BlockingQueue<Runnable> runnables;
public InnerThread(BlockingQueue<Runnable> runnables) {
this.runnables = runnables;
}
@Override
public void run() {
while (true) {
try {
Runnable runnable = runnables.take();
System.out.println(getName() + " run ");
runnable.run();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
4 回答1.7k 阅读✓ 已解决
4 回答1.5k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
4 回答2.3k 阅读
3 回答1.3k 阅读✓ 已解决
2 回答838 阅读✓ 已解决
2 回答1.4k 阅读
我猜题主是使用 Executors.newCachedThreadPool();这个方法来创建线程池的吧,不知道你有没有点进去这个方法看看里面是怎么来创建线程池的。
我就来帮你看下源码。
创建线程池最终调用的是这个方法。
来看下这几个参数
corePoolSize :核心线程数量,就算线程的状态是闲置也不会销毁
maximumPoolSize: 最大线程数量
keepAliveTime :超出核心线程的数量可以闲置多久,超过这个时间就销毁了
unit :keepAliveTime的单位
workQueue: 从泛型可以看出来里面装的都是Runnable,而且是一个阻塞的队列
ThreadFactory: 线程工厂
RejectedExecutionHandler: 任务拒绝策略,有四种可选
然后再看execute方法
线程池是先找到一个闲置的线程,然后从workQueue这个阻塞队列中拿到你提交的任务(Runnable)然后去跑。(理想状态)
当然是使用线程池咯,可以设置核心线程数量为1。