在线程池的编程模式下,任务是提交给整个线程池,而不是直接交给某个线程,线程池在拿到任务之后,在内部找到空闲的线程去执行该任务。其实就是对线程的封装。
任务是提交给线程池的,一个线程只能同时执行一个任务,但是可以同时向一个线程池提交多个任务。
固定线程池:三个线程的固定线程池
public static void main(String[] args){
//新建含有三个线程的固定线程池
//ExecutorService threadPool= Executors.newFixedThreadPool(3);
//由于线程池中只是提交了三个线程,所以即使下面的i最大值为5,依然只会有三个线程
for(int i=1;i<6;i++){
final Integer taskNum=i;
threadPool.execute(new Runnable() {
@Override
public void run(){
for(int j=0;j<10;j++){
try{
Thread.sleep(100);
}catch(InterruptedException e){
System.out.println(Thread.currentThread().getName()+"Error:"+e.toString());
}
System.out.println(Thread.currentThread().getName()+" is loop of "+j+" of task "+taskNum);
}
}
});
}
System.out.println("all of the five threads are done!");
// threadPool.shutdown();//等所有线程都空着了(闲了)就关闭线程池
// threadPool.shutdownNow();//shutDownNow意味着直接关闭当前的线程池,不管是否还有线程在进行
}
使用shutdow()和shutdownNow()方法进行关闭线程池的两种情况截图:
shutdown();三个线程分别将三个任务执行完之后,去执行剩下的两个任务(i最大值=5)直到所有的任务都被执行完,所有的线程空闲,就关闭线程池。
shutdownNow();只要池中的线程数执行一遍,就关闭线程池,不论任务有几个。本例中就是三个线程只执行三个任务,执行45任务的时候就会因异常而中断。
将固定线程池改为缓存线程池,将shutdow()都注释掉:
ExecutorService threadPool=Executors.newCachedThreadPool();
此时线程池中的五个线程都会执行循环。
创建一个单一的线程池:
//创建一个单一的线程池,一个线程死掉之后会重新找一个新的线程去替补。
ExecutorService threadPool= Executors.newSingleThreadExecutor();
用线程池启动定时器:
1.每隔固定时间执行一次:
2.固定时间后只执行一次:
需要提醒大家的是:定时器中可以指定任意时间(DateTime)执行线程,但是线程池中没有这个方法,所以要想指定某一个特定时间,只能将参数中的delay设置为date.getTime()- System.currentTimeMillis()。其实只是设置起来有点麻烦,效果还是能达到的。
注意上面两个scheduledExecutorService要记得shutdown,不然线程会一直执行下去。
corePoolSize决定了线程池中有几个线程可以去执行该定时任务。