线程池的创建其实有很多办法,但是jdk为了方便,创建了4中常用的线程池对象:
1.newCachedThreadPool();
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
2.newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
3.newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行
4.newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
下面我们分别对应四种方式,写一个demo。
一、先写一个多线程对象:
import java.util.Date;
public class ThreadTest extends Thread{
public void run(){
//输出当前线程名字,和当前时间
System.out.println(Thread.currentThread().getName()+";"+new Date());
}
}
二、可缓存线程池:newCachedThreadPool
public class Test {
public static void main(String[] args) {
//创建一个newCachedThreadPool。可缓存线程池。
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
//创建多线程对象
Thread t1=new ThreadTest();
Thread t2=new ThreadTest();
Thread t3=new ThreadTest();
Thread t4=new ThreadTest();
Thread t5=new ThreadTest();
//执行线程池中线程
cachedThreadPool.execute(t1);
cachedThreadPool.execute(t2);
cachedThreadPool.execute(t3);
cachedThreadPool.execute(t4);
cachedThreadPool.execute(t5);
//关闭线程池
cachedThreadPool.shutdown();
}
}
启动main方法,控制台输出:
注意线程名字和线程抢占的时间,说明线程是同时进行的。
哪怕我们创建10个线程:
三、定长线程池:newFixedThreadPool;
public class Test {
public static void main(String[] args) {
//创建一个定长线程池,长度是2
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);
//创建多线程对象
Thread t1=new ThreadTest();
Thread t2=new ThreadTest();
Thread t3=new ThreadTest();
Thread t4=new ThreadTest();
Thread t5=new ThreadTest();
//执行线程池中线程
cachedThreadPool.execute(t1);
cachedThreadPool.execute(t2);
cachedThreadPool.execute(t3);
cachedThreadPool.execute(t4);
cachedThreadPool.execute(t5);
//关闭线程池
cachedThreadPool.shutdown();
}
}
启动main方法,控制台输出:
不管创建多少个,线程数永远只有2个。而且也是同时经行的。
四、单线程池,newSingleThreadExecutor
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
Thread t1=new ThreadTest();
Thread t2=new ThreadTest();
Thread t3=new ThreadTest();
Thread t4=new ThreadTest();
Thread t5=new ThreadTest();
//执行线程池中线程
singleThreadExecutor.execute(t1);
singleThreadExecutor.execute(t2);
singleThreadExecutor.execute(t3);
singleThreadExecutor.execute(t4);
singleThreadExecutor.execute(t5);
//关闭线程池
singleThreadExecutor.shutdown();
启动main方法,控制台输出
一个线程在同一时间执行。
五、定长线程池支持定时器 newScheduledThreadPool
//创建一个定长线程池支持定时器 newScheduledThreadPool;长度是2
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName()+";"+new Date());
}
}, 1, 3, TimeUnit.SECONDS);
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName()+";"+new Date());
}
}, 1, 3, TimeUnit.SECONDS);
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName()+";"+new Date());
}
}, 1, 3, TimeUnit.SECONDS);
启动main方法,控制台输出:
启动三个定时的任务,但是只有2个线程。
当我们把线程数量定长到5个后:
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
启动main方法,控制台输出:
发现有三个线程,共同抢占资源了。
最后补充一点:
线程池的作用是,减少创建和销毁线程的时间。从而提高服务器的行性能。