酷特智能服装定制,seo课程在哪培训好,广告设计在哪里学,合肥网站建设百姓网线程饥饿死锁
在单线程的Executor中#xff0c;如果任务A将任务B提交给同一个Executor#xff0c;并且等待任务B的结果#xff0c;就会引发死锁线程池中所有正在执行任务的线程由于等待其他仍处于工作队列中的任务而阻塞
执行时间较长的任务
执行时间较长的任务不仅会造成…线程饥饿死锁
在单线程的Executor中如果任务A将任务B提交给同一个Executor并且等待任务B的结果就会引发死锁线程池中所有正在执行任务的线程由于等待其他仍处于工作队列中的任务而阻塞
执行时间较长的任务
执行时间较长的任务不仅会造成线程池阻塞也会增加执行时间较短的任务的服务时间
对于平台库的可阻塞方法都定义了限时版本如BlockingQueue.put若超过等待时间则可以中止任务或重新放回队列后续执行
设置线程池的大小
对于计算密集型的任务在有N个处理器的系统上线程池大小为N1能实现最优利用率
对于其他情况 ThreadPoolExecutor
通过一系列参数配置线程池
corePoolSize核心线程数当allowsCoreThreadTimeOuttrue且核心线程闲置时间超过keepAliveTime就会终止否则一直存活maximumPoolSize最大线程数超过后接下来的任务会被阻塞keepAliveTime非核心线程闲置时间超过后非核心线程会被回收当allowsCoreThreadTimeOuttrue同样作用于核心线程unit指定keepAliveTime的时间单位workQueue线程池的任务队列存储execute()提交的Runnable对象threadFactory线程工厂为线程池创建新线程handler当线程池已满或无法成功执行时使用饱和策略
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueueRunnable workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) {if (corePoolSize 0 ||maximumPoolSize 0 ||maximumPoolSize corePoolSize ||keepAliveTime 0)throw new IllegalArgumentException();if (workQueue null || threadFactory null || handler null)throw new NullPointerException();this.corePoolSize corePoolSize;this.maximumPoolSize maximumPoolSize;this.workQueue workQueue;this.keepAliveTime unit.toNanos(keepAliveTime);this.threadFactory threadFactory;this.handler handler;
}管理队列任务
ThreadPoolExecutor允许提供一个BlockingQueue保持执行的任务基本队列有3种
无界队列newFixedThreadPool和newSingleThreadPool使用LinkedBlockingQueue有界队列如ArrayBlockingQueue有界的LinkedBlockingQueue和PriorityBlockingQueue同步移交newCachedThreadPool使用SynchronousQueue避免任务排队直接将任务从生产者移交给工作者线程
只有当任务互相独立线程池和工作队列设置界限才是合理的否则有界的线程池或队列可能导致线程饥饿死锁问题
饱和策略
当有界队列被填满后将会使用饱和策略RejectedExecutionHandler其包含
AbortPolicy默认策略抛出RejectedExecutionException调用者需捕获异常并自行处理CallerRunsPolicy将某些任务回退给调用者在调用了execute的线程中执行该任务如主线程提交任务会退回给主线程执行DiscardPolicy抛弃新提交的任务DiscardOlderstPolicy抛弃下一个将被执行的任务尝试重新提交新的任务
线程工厂
线程池通过线程工厂创建线程默认线程工厂创建一个新的非守护线程可通过重新ThreadFatory的newThread方法自定义配置信息每次创建线程都会调用该方法
如下为线程池中的线程设置名字和setUncaughtExceptionHandler
class MyThreadFactory implements ThreadFactory {Overridepublic Thread newThread(Runnable r) {Thread thread new Thread(AAA);thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {Overridepublic void uncaughtException(NonNull Thread t, NonNull Throwable e) {System.out.println(e.toString());}});return thread;}
}修改线程池配置
可将对象转为ThreadPoolExecutor再调用对应属性的setter方法但newSingleThreadExecutor除外其使用unconfigurableExecutorService封装只暴露了ExecutorService中的方法
public class A {public ExecutorService test() {ExecutorService cachedThreadPool Executors.newCachedThreadPool();if (cachedThreadPool instanceof ThreadPoolExecutor) {((ThreadPoolExecutor) cachedThreadPool).setCorePoolSize(10);}return Executors.unconfigurableExecutorService(cachedThreadPool);}
}扩展ThreadPoolExecutor
可在子类中重写
beforeExecute线程执行前调用afterExecute线程执行完后调用无论线程正常返回还是抛出异常都会调用但任务完成后出现Error则不会terminated线程池关闭时调用