在同等数量级的操作下,使用线程池的效率要远远高于单线程。线程池可以降低创建线程带来的开销。而线程池中的线程结束后进行的是回收操作而不真的将线程销毁。而在这个过程过,线程池带来的内存消耗肯定会大于单线程。在使用线程池的时候要慎重这个问题。下面进行两个方法,分别来测试下。
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadpoolDemo1 {
static void useThreadPool(int count) {
//定义存储集合
final List<Integer> list = new LinkedList<Integer>();
long startTime = System.currentTimeMillis();
ThreadPoolExecutor tpe = new ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(count) );
//产生随机数
final Random random = new Random();
for (int i=0; i < count; i++) {
tpe.execute(new Runnable() {
@Override
public void run() {
list.add(random.nextInt());
}
});
}
tpe.shutdown();
try {
tpe.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(System.currentTimeMillis() - startTime);
System.out.println(list.size());
}
static void useOneThread(int count){
final List<Integer> list = new LinkedList<Integer>();
long startTime = System.currentTimeMillis();
//产生随机数
final Random random = new Random();
for (int i=0; i<count; i++) {
Thread thread = new Thread(){
public void run() {
list.add(random.nextInt());
}
};
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(System.currentTimeMillis() - startTime);
System.out.println(list.size());
}
public static void main(String[] args) {
useThreadPool(20000);
useOneThread(20000);
}
}
在count参数为同值的时候,使用线程池会比单独创建线程的速度要快好几倍。
使用线程池的好处:
1)减少了创建和销毁线程的次数,线程可以被重复利用
2)线程池中的线程可以被程序员调节。减少系统内存的消耗。
线程池的使用:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolDemo2 {
// 创建一个可重复利用的单线城池
private void testSingleThreadExecutor() {
ExecutorService pool = Executors.newSingleThreadExecutor();
Thread t1 = new MyThread();
Thread t2 = new MyThread();
Thread t3 = new MyThread();
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.shutdown();
}
// 创建一个固定大小的线程池
private void testFixedThreadPool() {
ExecutorService pool = Executors.newFixedThreadPool(3);
Thread t1 = new MyThread();
Thread t2 = new MyThread();
Thread t3 = new MyThread();
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.shutdown();
}
// 创建具有定时功能的线程池
private void testScheduledThreadPoolExecutor() {
ScheduledThreadPoolExecutor poolExecutor = new ScheduledThreadPoolExecutor(1);
poolExecutor.scheduleAtFixedRate(new Runnable() {
// 每隔一段时间就触发异常
@Override
public void run() {
// throw new RuntimeException();
System.out.println("================");
}
}, 1000, 5000, TimeUnit.MILLISECONDS);
poolExecutor.scheduleAtFixedRate(new Runnable() {
// 每隔一段时间打印系统时间,证明两者是互不影响的
@Override
public void run() {
System.out.println(System.currentTimeMillis());
}
}, 1000, 2000, TimeUnit.MILLISECONDS);
}
}
ThreadPoolExecutor:
创建ThreadPoolExecutor的参数:
corePoolSize: 池中所保存的线程数,包括空闲线程。
maximumPoolSize:池中允许的最大线程数。
keepAliveTime:当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
Unit:keepAliveTime 参数的时间单位。
workQueue:执行前用于保持任务的队列。此队列仅保持由 execute方法提交的 Runnable任务。
threadFactory:执行程序创建新线程时使用的工厂。
Handler:由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序。