【Java |
您所在的位置:网站首页 › io密集型线程池几个 › 【Java |
文章目录
1. 线程池简介2. 创建线程池3. 工厂模式简介4. 线程池的使用5. 实现线程池6. ThreadPoolExecutor的构造方法讲解7. 线程池的线程数量,如何确定?
1. 线程池简介
Java线程池是一种用于管理和重用线程的机制,它可以在需要执行任务时,从线程池中获取线程,执行任务,然后将线程放回池中,以便后续使用。线程池可以有效地管理线程的数量,提高程序的性能和资源利用率。 为什么从线程池里面取线程比直接创建线程快呢? 创建线程是要在操作系统内核中完成的,涉及"用户态"到"内核态"切换操作. 这个切换是有一定开销的. 而线程池取线程是纯的用户态实现. 2. 创建线程池注意这里线程池创建的写法: ExecutorService executorService = Executors.newCachedThreadPool();这里并没有new,而是通过Executors的静态方法newCachedThreadPool来创建的,这里涉及到一种设计模式-“工厂模式” 3. 工厂模式简介工厂模式(Factory Pattern)是一种创建对象的设计模式,它提供了一种封装对象创建过程的方式,使得客户端代码与具体对象的实例化过程解耦。 工厂模式的主要目的是通过一个工厂类来创建对象,而不是直接在客户端代码中使用new关键字来实例化对象。这样可以隐藏具体对象的创建细节,提供更灵活、可扩展的设计。 详细可参考:工厂模式 | 菜鸟教程 4. 线程池的使用线程池的使用很简单,只需要实现submit方法即可 public class Demo19 { public static void main(String[] args) { ExecutorService executorService = Executors.newCachedThreadPool(); executorService.submit(new Runnable() { @Override public void run() { System.out.println("线程执行的任务1"); } }); executorService.submit(new Runnable() { @Override public void run() { System.out.println("线程执行的任务2"); } }); executorService.submit(new Runnable() { @Override public void run() { System.out.println("线程执行的任务3"); } }); } }这里主要是将任务放到线程池中,线程池里的线程就会去执行这些任务 运行结果: 5. 实现线程池要想实现线程池,要先弄清楚线程池有哪些功能. 一个线程池中可以同时提交N个任务,线程池里有M个线程来执行这N个任务 如何将N个任务分配给M个线程呢? 可以使用生产者-消费者模型解决这个问题. 以下是一个线程池的简易实现: public class MyThreadPool { private BlockingQueue blockingQueue = new public class MyThreadPool { private BlockingQueue blockingQueue = new LinkedBlockingQueue(); public void submit(Runnable runnable) throws InterruptedException { // 将任务添加到阻塞队列中 blockingQueue.put(runnable); } public MyThreadPool(int m){ // 创建m个线程 for (int i = 0; i // 让它一直扫描阻塞队列 while (true) { try { // 取出任务,并执行 Runnable runnable = blockingQueue.take(); runnable.run(); } catch (InterruptedException e) { throw new RuntimeException(e); } } }); t.start(); } } }测试上述代码: public class Demo20 { public static void main(String[] args) throws InterruptedException { MyThreadPool pool = new MyThreadPool(5); for (int i = 0; i @Override public void run() { System.out.println("任务"+ temp); } }); } } }运行结果: 不过上述代码中创建的线程数量是"固定"的,可根据需要自行调整 6. ThreadPoolExecutor的构造方法讲解ThreadPoolExecutor是Java中线程池的一个具体实现类,它实现了ExecutorService接口。ExecutorService是一个高级的线程池管理接口,提供了更多的灵活性和功能。 而ThreadPoolExecutor这个类的构造方法比较复杂 参数: corePoolSize - 即使空闲时仍保留在池中的线程数,除非设置 allowCoreThreadTimeOut maximumPoolSize - 池中允许的最大线程数 keepAliveTime - 当线程数大于内核时,这是多余的空闲线程在终止前等待新任务的最大时间。 unit - keepAliveTime参数的时间单位 workQueue - 用于在执行任务之前使用的队列。 这个队列将仅保存execute方法提交的Runnable任务。(自己传入的任务队列,如果传了就用传入的队列.如果不传,就线程池就去创建) threadFactory - 执行程序创建新线程时使用的工厂 handler -任务执行被拒绝时使用的处理程序,因为达到线程限制和队列容量 任务执行被拒绝时使用的程序有以下四个: 实际开发中,主要根据需求选择这里的拒绝策略进行处理. 7. 线程池的线程数量,如何确定?线程池可以自定义线程的数量 那么在实际开发中,线程池的线程数量设置成多少比较合适? 这个问题主要取决于以下几点: 任务类型:不同类型的任务对线程数量的需求不同。如果是CPU密集型任务,通常线程数量应该与CPU核心数相近,以充分利用CPU资源。如果是IO密集型任务,可以设置较多的线程数量,以便处理并发的IO操作。系统资源:需要考虑系统的硬件资源和性能。如果系统资源有限,例如内存、CPU等,线程数量应适当控制,避免过多的线程导致资源竞争和性能下降。并发量:需要根据任务的并发量来确定线程数量。如果任务并发量较高,可以增加线程数量以提高任务处理能力。如果任务并发量较低,可以减少线程数量以节省资源。响应时间:需要考虑任务的响应时间要求。如果任务需要快速响应,可以增加线程数量以减少等待时间。如果任务的响应时间可以接受较长的延迟,可以减少线程数量以节省资源。线程池类型:不同类型的线程池有不同的线程数量限制。例如,FixedThreadPool固定线程池的线程数量是固定的,CachedThreadPool可缓存线程池的线程数量是动态调整的。这个问题要考虑的因素有很多,最简单的方法就是去测试 将线程分为设置成不同的数量,然后观察系统的性能和任务的执行情况,根据需要逐步调整线程数量,找到最优的配置。 感谢你的观看!希望这篇文章能帮到你! 专栏: 《从零开始的Java学习之旅》在不断更新中,欢迎订阅! “愿与君共勉,携手共进!” |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |