packagecom.dreamer.multithread.day09;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;publicclassDemo03{publicstaticvoidmain(String[] args){ExecutorService pool =Executors.newSingleThreadExecutor();/*第一个任务执行失败后,后续任务会继续执行*/
pool.execute(()->{int i =1/0;System.out.println(Thread.currentThread().getName()+" first running");});
pool.execute(()->{System.out.println(Thread.currentThread().getName()+" second running");});
pool.execute(()->{System.out.println(Thread.currentThread().getName()+" third running");});}}
packagecom.dreamer.multithread.day09;importjava.util.ArrayList;importjava.util.Collection;importjava.util.List;importjava.util.concurrent.Callable;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.Future;publicclassDemo2{publicstaticvoidmain(String[] args)throwsInterruptedException,ExecutionException{ExecutorService pool =Executors.newCachedThreadPool();Collection<Callable<String>> tasks =newArrayList();for(int i =0; i <10; i++){int round = i;
tasks.add(newCallable(){@OverridepublicObjectcall()throwsException{System.out.println(Thread.currentThread().getName()+" running");return"success:"+ round;}});}List<Future<String>> results = pool.invokeAll(tasks);for(Future<String> result : results){System.out.println(result.get());}}}
4. invokeAny
集合中之要有一个任务执行完毕,其他任务就不再执行
packagecom.dreamer.multithread.day04;importjava.util.ArrayList;importjava.util.Collection;importjava.util.concurrent.Callable;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.TimeUnit;publicclassTest03{publicstaticvoidmain(String[] args)throwsInterruptedException,ExecutionException{ExecutorService service =Executors.newFixedThreadPool(1);Collection<Callable<String>> tasks =newArrayList<>();
tasks.add(()->{System.out.println("first task");TimeUnit.SECONDS.sleep(1);return"success";});
tasks.add(()->{System.out.println("second task");TimeUnit.SECONDS.sleep(2);return"success";});
tasks.add(()->{System.out.println("third task");TimeUnit.SECONDS.sleep(3);return"success";});// 任何一个任务执行完后,就会返回结果String result = service.invokeAny(tasks);System.out.println(result);}}
五、关闭线程池
1. shutdown
将线程池的状态改变为SHUTDOWN状态
不会接受新任务,已经提交的任务不会停止
不会阻塞调用线程的执行
voidshutdown();
packagecom.dreamer.multithread.day09;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.TimeUnit;publicclassDemo04{publicstaticvoidmain(String[] args){ExecutorService pool =Executors.newFixedThreadPool(1);
pool.submit(()->{try{TimeUnit.SECONDS.sleep(2);System.out.println(Thread.currentThread().getName()+" first running");}catch(InterruptedException e){
e.printStackTrace();}});
pool.submit(()->{try{TimeUnit.SECONDS.sleep(2);System.out.println(Thread.currentThread().getName()+" second running");}catch(InterruptedException e){
e.printStackTrace();}});
pool.submit(()->{try{TimeUnit.SECONDS.sleep(2);System.out.println(Thread.currentThread().getName()+" third running");}catch(InterruptedException e){
e.printStackTrace();}});// 不会阻塞主线程的执行
pool.shutdown();System.out.println("main thread ending");}}
2. shutdownNow
不会接受新任务
没执行的任务会打断
将等待队列中的任务返回
List<Runnable>shutdownNow();
packagecom.dreamer.multithread.day09;importjava.util.List;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.TimeUnit;publicclassDemo04{publicstaticvoidmain(String[] args){ExecutorService pool =Executors.newFixedThreadPool(1);
pool.submit(()->{try{TimeUnit.SECONDS.sleep(2);System.out.println(Thread.currentThread().getName()+" first running");}catch(InterruptedException e){
e.printStackTrace();}});
pool.submit(()->{try{TimeUnit.SECONDS.sleep(2);System.out.println(Thread.currentThread().getName()+" second running");}catch(InterruptedException e){
e.printStackTrace();}});
pool.submit(()->{try{TimeUnit.SECONDS.sleep(2);System.out.println(Thread.currentThread().getName()+" third running");}catch(InterruptedException e){
e.printStackTrace();}});// 不会阻塞主线程的执行List<Runnable> leftOver = pool.shutdownNow();System.out.println(leftOver.size());// 2System.out.println("main thread ending");}}
六、线程池数量
过小,导致cpu资源不能充分利用,浪费性能
过大,线程上下文切换,导致占用内存过多,浪费性能
1. CPU密集型
如果线程的任务主要是和cpu资源打交道,成为CPU密集型
线程数量: 核心数+1
+1: 保证某线程由于某些原因(操作系统方面)导致暂停时,额外线程可以启动,不浪费CPU资源
2. IO密集型
IO操作,RPC调用,数据库访问时,CPU是空闲的,称为IO密集型
线程数 = 核数* 期望cpu利用率* (cpu计算时间+cpu等待时间)/cpu计算时间
七、调度功能
1. 延时执行
如果希望线程延时执行任务
packagecom.dreamer.multithread.day09;importjava.util.concurrent.Executors;importjava.util.concurrent.ScheduledExecutorService;importjava.util.concurrent.TimeUnit;publicclassDemo05{publicstaticvoidmain(String[] args){// 两个线程,分别可以延时执行不同的任务ScheduledExecutorService pool =Executors.newScheduledThreadPool(2);// 延时1s后执行
pool.schedule(newRunnable(){@Overridepublicvoidrun(){System.out.println(Thread.currentThread().getName()+" first running");}},1,TimeUnit.SECONDS);// 延时5s后执行
pool.schedule(newRunnable(){@Overridepublicvoidrun(){System.out.println(Thread.currentThread().getName()+" second running");}},5,TimeUnit.SECONDS);}}
packagecom.dreamer.multithread.day09;importjava.util.concurrent.Executors;importjava.util.concurrent.ScheduledExecutorService;importjava.util.concurrent.TimeUnit;publicclassDemo06{publicstaticvoidmain(String[] args){// 如果是单个线程,则延时的任务是串行执行的ScheduledExecutorService pool =Executors.newScheduledThreadPool(1);// 如果一个线程出错,则会再次创建一个线程来执行任务
pool.schedule(newRunnable(){@Overridepublicvoidrun(){int i =1/0;System.out.println(Thread.currentThread().getName()+" first running");}},1,TimeUnit.SECONDS);
pool.schedule(newRunnable(){@Overridepublicvoidrun(){System.out.println(Thread.currentThread().getName()+" second running");}},2,TimeUnit.SECONDS);}}
2. 定时执行
scheduleAtFixedRate
scheduleWithFixedDelay
packagecom.dreamer.multithread.day09;importjava.util.concurrent.Executors;importjava.util.concurrent.ScheduledExecutorService;importjava.util.concurrent.TimeUnit;publicclassDemo07{publicstaticvoidmain(String[] args){ScheduledExecutorService pool =Executors.newScheduledThreadPool(2);// 定时执行任务
pool.scheduleWithFixedDelay(newRunnable(){@Overridepublicvoidrun(){try{TimeUnit.SECONDS.sleep(2);}catch(InterruptedException e){
e.printStackTrace();}System.out.println("task is running");}},3,2,TimeUnit.SECONDS);// 初始延时, 任务间隔时间, 任务间隔时间单位}}
八、异常处理
1. 不处理异常
任务执行过程中,业务中的异常并不会抛出
packagecom.dreamer.multithread.day09;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;publicclassDemo08{publicstaticvoidmain(String[] args){ExecutorService pool =Executors.newFixedThreadPool(1);
pool.submit(newRunnable(){@Overridepublicvoidrun(){int i =1/0;System.out.println(Thread.currentThread().getName()+" task running");}});}}
2. 任务执行者自己处理
packagecom.dreamer.multithread.day09;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;publicclassDemo08{publicstaticvoidmain(String[] args){ExecutorService pool =Executors.newFixedThreadPool(1);
pool.submit(newRunnable(){@Overridepublicvoidrun(){try{int i =1/0;System.out.println(Thread.currentThread().getName()+" task running");}catch(Exception e){
e.printStackTrace();return;}}});}}
3. 线程池处理
packagecom.dreamer.multithread.day09;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.Future;importjava.util.concurrent.TimeUnit;publicclassDemo08{publicstaticvoidmain(String[] args)throwsInterruptedException,ExecutionException{ExecutorService pool =Executors.newFixedThreadPool(1);Future<?> result = pool.submit(newRunnable(){@Overridepublicvoidrun(){int i =1/0;System.out.println(Thread.currentThread().getName()+" task running");}});TimeUnit.SECONDS.sleep(1);// 获取结果的时候,就可以把线程执行任务过程中的异常报出来System.out.println(result.get());}}