线程池的引入
不适用线程池的情况,每当来一个任务,我们就要new一个Thread对象,很麻烦。而且new完执行了任务就死掉了,又来一个任务又要new一个Thread,可能开销会很大,所以设想,如果每个线程对象都可以重复执行任务,那岂不美哉?于是线程池就被搞出来了。
线程池
我们举这样一个例子:银行窗口与办理业务的人们。我们开设有限个银行窗口,都支持办理各种业务。人们来银行办理业务,取票排队,当被叫到的时候,就去办理业务。每个窗口办理完一个业务,就叫队列里下个客户来,就是这么个流程。
这个例子中:银行->线程池。窗口->线程数量。需要办业务的人(的业务)->需要执行的线程任务。
简单吧!
线程池案例
创建线程池,指定线程数量
ExecutorService threadPool = Executors.newFixedThreadPool(2);
for循环模拟线程任务的创建
线程任务,就是实现Runnable的对象。
Runnable r = new Runnable() { @Override public void run() { Thread t = Thread.currentThread(); System.out.println(t.getName()+":正在创建线程..."); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } t = Thread.currentThread(); System.out.println(t.getName()+":完毕创建线程..."); } };
添加任务到执行队列,等待被执行。
threadPool.execute(r);
案例完整代码
package _20200119; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPool { public static void main(String[] args) { ExecutorService threadPool = Executors.newFixedThreadPool(2); for(int i=0;i<5;i++) { Runnable r = new Runnable() { @Override public void run() { Thread t = Thread.currentThread(); System.out.println(t.getName()+":正在创建线程..."); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } t = Thread.currentThread(); System.out.println(t.getName()+":完毕创建线程..."); } }; threadPool.execute(r); System.out.println("指派了一个任务..."); } //线程池关闭: //执行完关闭:线程池中没有执行任务的线程,就关掉线程池 threadPool.shutdown(); //立即关闭 // threadPool.shutdownNow(); } }
总结:虽然是线程池,但用到的类都没有ThreadPool这个词好伐!这个点有点转弯。