package com.aaa.threaddemo; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /* *一 四种常见的线程池是啥? * newFixedThreadPool * 1.创建一个可重用固定线程数的线程池, 2.使用共享的无界队列方式来运行这些线程。 * * newCachedThreadPool * 1.可根据需要创建新线程的线程池 2.旧的线程可用时将重用他们 3.对短期异步的程序 可提高程序性能 * * newSingleThreadExecutor * 1.返回一个线程池,只有一个线程 2.可以在旧的线程挂掉之后,重新启动一个新的线程来替代它。 达到起死回生的效果。 * * newScheduledThreadPool * 给定一个延迟后,可以运行命令或者定期执行。 * java中线程池的顶级接口是Executor 严格而言,正在的线程池是ExecutorService * *二 阻塞队列 LinkedBlockingQueue 使用注意事项? * *三 线程池提交任务的方式? * *四 shutdown 的使用方式? * *五 线程池中的常用参数设置? */ /* 二 newFixedThreadPool * 1.创建一个固定大小的线程池 * 2.提交一个任务,就创建一个线程,直到线程池的最大容量。 * 3.线程池的大小达到最大值,就保持不变。 * 4.有执行异常而结束的线程,线程池会补充一个新的线程。 * 5.使用完毕,必须手动关闭线程池,否则会一直存在内存中 * * 看一下newFiexdThreadPool()的内心世界 public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); */ public class ThreaPoolUser { public static void main(String[] args) { ExecutorService fixedPool = Executors.newFixedThreadPool(2); //创建一个可重用,固定线程数的线程池 容量为 2 /* 线程池的容量是2,我这里放入了3个线程,线程池会如何处理? 可以看到这里有个没有指定容量的队列 linkedBlockingQueue,此时的队列就是一个无边界的队列。 可以不断的在队列中添加任务 多放一个问题不大,300000个呢? 任务过多,就会导致内存溢出。 【注意!】 linkedBlockingQueue 本身是一个用链表结实现的有界阻塞队列,容量是可以设置的。 较好的使用方式 五 ExecutorService executorService = new ThreadPoolExecutor( 10, //核心线程数 13, //线程池最大容量 60L, //非核心线程的生存时间 TimeUnit.SECONDS, //生存的时间单位 new ArrayBlockingQueue(10)); //设置队列中的容量 */ FiexdDemo fiexdDemo = new FiexdDemo(); FiexdDemo fiexdDemo2 = new FiexdDemo(); FiexdDemo fiexdDemo3 = new FiexdDemo(); /* 三 线程池提交任务的方式有两种 * 1.execute * 提交的是runnable类型的任务,下文的线程是继承了thread,thread又是runnable的实现类。 * 提交是没有返回值的 * 遇到异常直接抛出 * * 2.submit * runnable 和 callable 都可提交 * 返回一个future类型的对象 * 将异常存储,调用future get方法 才会抛出异常 */ fixedPool.execute(fiexdDemo); fixedPool.execute(fiexdDemo2); fixedPool.execute(fiexdDemo3); /* 四 shutdown() * 1.把线程池的状态设置为 shutdown,但是并不会马上停止 * 2.停止接受外部的submit 任务 * 3.线程池正在运行的任务,队列中等待的任务,会执行完 * 4.完成后,才是真正的停止 */ fixedPool.shutdown(); //手动关闭线程池 } } /* * 上面已经创建好了一个固定的线程池,这边创建一个多线程。 * 把线程放进 线程池中就完事了。 */ class FiexdDemo extends Thread{ @Override public void run() { System.out.println("我是一个线程"); System.out.println("[currentThread = ]" + Thread.currentThread().getName()); } }
看下结果