每次new Thread的时候,都会创建一个单线程,但是,我们在项目中基本都是使用线程池,本文主要整理了线程和线程池的优缺点。
new Thread的优缺点
优点:
通过new Thread()创建线程的API简单易用,结构清晰,对于执行单一的一次性任务十分便利。
缺点:
- 每次new Thread都新建对象,性能差;
- 没有线程管理者,可能会无限制新建线程,不仅会消耗系统资源,还会降低系统的稳定性,例如占用过多的系统资源导致OOM;
- 缺乏更多功能,比如定时、定期、并发数控制等功能。
线程池的优点
合理利用线程池能够带来三个好处:
- 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
- 提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
- 提高线程的可管理性。线程是稀缺资源,使用线程池可以进行统一的分配、调优和监控。
大家new Thread的方式会创建一个线程,在我们有大量的创建线程的时候这样的方法还会可靠吗?每一次new Thread都会重新创建一个线程,而线程的创建和销毁都需要耗时的。在jdk1.5的concurrent包中有一个Executors,他能使我们创建的线程得到复用,不会频繁的创建和销毁线程。
我们今天主要是我们使用了Executors和每次new一个Thread的对比。
public class Test001 {
private ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>();
private CountDownLatch latch = new CountDownLatch(100000);
ExecutorService es = Executors.newFixedThreadPool(4);
public static void main(String[] args) {
Test001 test001 = new Test001();
long timeStart = System.currentTimeMillis();
test001.start();
System.out.println(System.currentTimeMillis()-timeStart);
}
public void start(){
for (int i = 0; i < 100000; i++) {
Runnable001 runnable001 = this.new Runnable001(i);
es.submit(runnable001);
// new Thread(runnable001).start();
}
es.shutdown();
try {
//等待latch计数为0
latch.await();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(queue.size());
}
private class Runnable001 implements Runnable{
private int value;
public Runnable001(int value) {
this.value = value;
}
@Override
public void run() {
queue.offer(value+"");
latch.countDown();//latch计数减一
}
}
}
首先是使用Executors的情况,运行结果如下:
100000
93
注释:es.submit(runnable001);放开:new Thread(runnable001).start();得到结果:
100000
10555
可见差距之大,如果有大量的需要使用线程的话不妨考虑一下线程池