关于线程池的讲解:
在线程池的编程模式下,任务是提交给整个线程池,而不是直接交给某个线程,线程池在拿到任务后,它就在内部找有无空闲的线程,再把任务交给内部某个空闲的线程,这就是封装。记住,任务是提交给整个线程池,一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务。
固定大小的线程池&缓存线程池-----------------:
步骤1:用3个大小的固定线程池去执行10个内部循环10次就结束的任务,为了观察固定线程池下的其他任务一直再等待,希望打印出正在执行的线程名、任务序号和任务内部的循环次数,刚开始看到只有3个线程在执行,并看到任务前仆后继的效果。注意:这10个任务要用各自独立的runnable对象,才能看到任务的序号。
在线程池的编程模式下,任务是提交给整个线程池,而不是直接交给某个线程,线程池在拿到任务后,它就在内部找有无空闲的线程,再把任务交给内部某个空闲的线程,这就是封装。记住,任务是提交给整个线程池,一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务。
固定大小的线程池&缓存线程池-----------------:
步骤1:用3个大小的固定线程池去执行10个内部循环10次就结束的任务,为了观察固定线程池下的其他任务一直再等待,希望打印出正在执行的线程名、任务序号和任务内部的循环次数,刚开始看到只有3个线程在执行,并看到任务前仆后继的效果。注意:这10个任务要用各自独立的runnable对象,才能看到任务的序号。
步骤2:改为缓存线程池,可以看到当前有多少个任务,就会分配多少个线程为之服务。
举例:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ThreadPoolTest {
public static void main(String[] args) {
//ExecutorService service = Executors.newFixedThreadPool(3);
ExecutorService service = Executors.newCachedThreadPool();
for(int i=1;i<=10;i++){
final int sequence = i;
//仔细品味runnable对象放到循环里面和外面的区别,为了让每个对象有自己独立的编号
service.execute(new Runnable(){
public void run() {
try{Thread.sleep(200);}catch(Exception e){}
for(int j=1;j<=5;j++){
System.out.println(Thread.currentThread().getName() + "is serving "
+ sequence + " task:" + "loop of " + j);
}
}
});
}
/*
用下面这句代码来说明上面的代码是在提交任务,并且所有的任务都已经提交了,但任务是什么时候执行的,则是由线程池调度的!
*/
System.out.println(“all task have committed!”);
//注意与service.shutdownNow()的区别。
service.shutdown();
ScheduledExecutorService scheduledService = Executors.newScheduledThreadPool(1);
scheduledService.scheduleAtFixedRate(
new Runnable(){
public void run() {
System.out.println("bomb!!!");
}},
5,
1,
TimeUnit.SECONDS);
}
}