线程池
在说线程池之前先提一下线程的一种创建方式:
MyRuunable run=new MyRuunable();//继承了Ruunable接口的实现类的对象,其实我们可以把run看成是线程需要跑的任务
Thread th=new Thread(run);//Thread就是线程,th就是线程对象,我们把run这个任务提交给th这个线程,然后线程执行run这个任务。
明白了上面的意思再来说线程池:
线程池顾名思义,就是一个装线程的池子,但是这个池子里的线程是不能跑起来的,因为池子里的线程
并没有得到任务:就是没有获得上面讲的run对象,如果想让池子里的线程跑起来那么我们就需要给线程
池里的线程提交一个任务。
创建线程池有两种方法:
先来说比较简单的一种方法:
代码:
public static void main(String[] args) { //创建线程池的第一种方法 ExecutorService contralPool = Executors.newFixedThreadPool(2);//通过Executors类的静态方法newFixedThreadPool //创建一个指定线程数量上限的线程池,并返回能联系和控制这个线程池的工具对象 //比如说用这个工具提交任务给池子 contralPool.submit(new Runnable() { @Override public void run() { String name = Thread.currentThread().getName(); System.out.println(name + "迎风少年运行了"); } }); //再次提交 contralPool.submit(new Runnable() { @Override public void run() { String name = Thread.currentThread().getName(); System.out.println(name + "迎风少年运行了"); } }); //再次提交 contralPool.submit(new Runnable() { @Override public void run() { String name = Thread.currentThread().getName(); System.out.println(name + "迎风少年运行了"); } }); }
第一种方法是通过: Executors(爱克斯卡特四)的静态方法newFixedThreadPool(新混池,个人记忆不喜勿喷)创建一个指定线程数量上限的池子;线程池的上限是2.
ExecutorService contralPool = Executors.newFixedThreadPool(2);
上面代码的运行结果是:
第三个任务只能等到第一个被执行的任务被线程执行完了才能进入池子被空闲的线程执行,因为线程以先执行,所以当线程1执行完了之后线程1会执行第三个任务
需要注意的是操作线程工具在submit()任务给线程吃之后,不用调用start方法,如果池子里有空闲线程,任务是直接执行的,没有空闲线程,任务就会进入阻塞(等待)
状态。
第二中创建线程池的方法:
public static void main(String[] args) { // method1(); //创建线程池的第二种方法: //其实第一种的创建方法也是间接性的创建第二种,只不过第二种的创建由于创建时的参数列表比较多,所以第一种算是一种简化 /* ThreadPoolExecutor contralpool=new ThreadPoolExecutor( 3, //核心线程 5,//最大线程数量 2, //空闲时间最长副线程被清理 TimeUnit.MILLISECONDS,//闲的时间单位 new ArrayBlockingQueue<>(10),//阻塞队列 Executors.defaultThreadFactory(),//线程工厂 new ThreadPoolExecutor.AbortPolicy());//拒绝策略 //一句口诀:核心最大,闲的时候排队进场去拒绝*/ ThreadPoolExecutor contralpool=new ThreadPoolExecutor( 3, 5, 2, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy() );
其他的任务拒绝策略有:
记住参数最多的应对起来才更方便
迎风少年