线程在并发程序中用的比较多,创建线程原始的有最基本的创建方式:
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
//todo
}
}).start();
}但如果通过这样创线程那就有点low了:
1)每次通过new Thread()创建对象性能不佳。
2)线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom。
3)缺乏更多功能,如定时执行、定期执行、线程中断。
这里可以用到Java提供的4种线程池来创建,分别为:
- newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
- newFixedThreadPool创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
- newScheduledThreadPool创建一个定长线程池,支持定时及周期性任务执行。
- newSingleThreadExecutor创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO,LIFO, 优先级)执行。
下面来比较一下这四种线程池:
newCachedThreadPlool:
public static void main(String[] args) {
ExecutorService cacheThreadPool = Executors.newCachedThreadPool();
for (int i=0; i<10; i++){
final int index = i;
try {
Thread.sleep(1000);
} catch (InterruptedException e){
}
cacheThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println("第" +index +"个线程" +Thread.currentThread().getName());
}
});
}
}输出结果为:
可以看出当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用去重新创建线程。
newFixedThreadPool:
public static void main(String[] args) {
ExecutorService fixedThreadPool =Executors. newFixedThreadPool(3);
for (int i =1; i<=5;i++){
final int index=i ;
fixedThreadPool.execute(new Runnable(){
@Override
public void run() {
try {
System.out.println("第" +index + "个线程" +Thread.currentThread().getName());
Thread.sleep(1000);
} catch(InterruptedException e ) {
}
}
});
}
}fixThreadPool会定义开启的线程数,例子中开启了三个,所以结果是前三个线程执行,第4个线程要等待1秒后执行。
newScheduledThreadPool:
该线程池可以安排在给定延迟后运行命令或者定期地执行。
延迟执行示例:
//corePoolSize - 池中所保存的线程数,即使线程是空闲的也包括在内。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)public static void main(String[] args) {
ScheduledExecutorService scheduledThreadPool= Executors.newScheduledThreadPool(3);
scheduledThreadPool.schedule(new Runnable(){
@Override
public void run() {
System.out.println("延迟3秒后执行");
}
}, 3, TimeUnit.SECONDS);
}上述实例会在开启3秒后执行。
定期执行示例:
public static void main(String[] args) {
ScheduledExecutorService scheduledThreadPool= Executors.newScheduledThreadPool(3);
scheduledThreadPool.scheduleAtFixedRate(new Runnable(){
@Override
public void run() {
System.out.println("延迟3秒后执行");
}
}, 1, 3, TimeUnit.SECONDS); //1:initialDelay, 3:period
}上述示例会在开启后延迟1秒执行,然后每3秒执行一次。
newSingleThreadExecutor:
public static void main(String[] args) {
ExecutorService singleThreadPool= Executors.newSingleThreadExecutor();
for(int i=1;i<=5;i++){
int index=i;
singleThreadPool.execute(new Runnable(){
@Override
public void run() {
try{
System.out.println("第"+index+"个线程");
Thread.sleep(2000);
}catch(InterruptedException e) {
e.printStackTrace();
}
} });
}
}会每2秒创一个线程,而且是顺序的执行各个任务,并且在任意给定的时间不会有多个线程是活动的,其实与newFixedThreadPool(1)效果是一样的。