您好,登录后才能下订单哦!
本篇内容主要讲解“Java线程池的使用方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java线程池的使用方法”吧!
在任务与执行策略之间的隐形耦合
依赖任务
使用线程封闭机制的任务
对相应时间敏感的任务
使用ThreadLocal的任务
在线程池中,如果任务依赖于其他任务,那么可能产生死锁。
程序清单8-1 在单线程中任务发生死锁
public class ThreadDeadLock { Executor executor = Executors.newSingleThreadExecutor(); public class RenderPageTask implements Callable<String> { @Override public String call() throws Exception { Future<String> header, footer; header = executor.execute(new LoadFileTask("header.html")); footer = executor.execute(new LoadFileTask("footer.html")); String page = renderBody(); //将发生死锁 -- 由于任务在等待子任务的结果 return header.get() + page + footer.get(); } } }
每当提交一个有依赖性的Executor任务时,要清楚地知道可能会出现线程"饥饿"死锁,因此需要在代码或配置Executor的配置文件中记录线程池的大小限制或配置限制。
除了在线程池大小上的显示限制外,还可能由于其他资源上的约束而存在一些隐式限制。如果应用程序使用一个包含10个连接的JDBC连接池,并且每个任务需要一个数据库连接,那么线程池就好像只有10个线程,因为当超过10个任务时,新的任务需要等待其他任务释放连接。
运行时间较长的任务
设置线程池的大小
配置ThreadPoolExecutor
ThreadPoolExecutor是线程池的真正实现,它构造方法提供了一系列参数来配置线程池。
public ThreadPoolExecutor (int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {...} public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHander hander) {...}
corePoolSize--线程池的核心线程数,默认情况下,核心线程会在线程池中一直存活,即使他们处于限制状态。如果将ThreadPoolExecutor的allowCoreThreadTimeOut属性
设置为true,那么闲置的线程核心线程在等待新任务到来时会有超时策略,这个时间间隔由keepAliveTime所指定,当等待时间超出keepAliveTime所指定的时长后,核心线程就会被终止。
maximumPoolSize--线程池所能容纳的最大线程数,当活动线程数达到这个数值后,后续的新任务将会被阻塞。
keepAliveTime--非核心线程闲置的超时时长,超过这个时长,非核心线程就会被回收。当ThreadPoolExecutor的属性allowCoreThreadTimeOut值为true时,keepAliveTime也作用于核心现程。
unit--用于指定keepAliveTime时间参数的单位,这是一个枚举,常用的有TimeOut.MILLISECONDS(毫秒)、TimeOut.SECONDS(秒)以及TimeOut.MINUTES(分钟)等。
workQueue--线程池中的任务队列,通过线程池的executor方法提交的Runnable对象会存储在这个参数中。
threadFactory--线程工厂,为线程池提供创建新线程的功能。ThreadFactory是一个接口,它只有一个方法:Thread newThread(Runnable r);
hander--不常用就不做介绍了。
ThreadPoolExecutor执行任务时大致遵循如下规则:
1 如果线程池中的线程数未达到核心数量,那么会直接启动一个核心线程来执行任务。
2 如果线程池中的线程数已达到或者超过核心数量,那么任务会被插入到任务队列中排队等待执行。
3 如果在步骤2中无法将任务插入到任务队列中,这往往是由于任务队列已满,这个时候如果线程数量未达到线程规定的最大值,那么会立刻启动一个非核心线程来执行任务。
4 如果步骤3中线程数量已经达到线程池规定的最大值,那么就拒绝执行任务,ThreadPoolExecutor会调用RejectedExecutionHander的rejectedExecution方法来通知调用者。
到此,相信大家对“Java线程池的使用方法”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。