java executable java中的线程和进程的区别
executor在java中扮演线程管理和任务调度的核心角色,它解耦了任务提交与执行机制。1. newfixedthreadpool创建固定大小的线程池,适用于任务数量稳定且对响应时间有要求的场景;2. newcachedthreadpool创建可动态调整大小的线程池,适合处理大量短期任务;3. newsinglethreadexecutor创建单线程池,保证任务顺序执行;4. newscheduledthreadpool创建支持定时和周期性任务的线程池。但不推荐使用executors直接线程池创建,因可能引发oom问题,建议通过threadpoolexecutor自定义,其参数包括核心线程数、最大线程数、空闲线程时间、任务队列、工厂线程及拒绝策略。关闭线程池时应优先调用shutdown()并配合awaitmination()确保任务完成,必要时调用shutdownnow()强制再关闭。
Executor在Java中扮演着线程管理和任务调度的核心角色,它允许我们将任务的提交与任务的执行机制解耦。简单来说,Executor就是一个执行Runnable任务的对象,它隐藏了线程创建和管理的复杂性,让开发者可以专注于业务逻辑。
线程池Executor的4种创建方式Executors.newFixedThreadPool(int) nThreads)
这是最常见的线程池方式之一。一个固定大小的线程池创建创建池中的线程数量始终保持不变。如果所有线程都已完成,新提交的任务将在队列中等待,直到立即有线程空闲。
学习“Java免费学习笔记(深入)”;优点:资源消耗可控,响应速度,适用于任务数量相对稳定,对响应时间有要求的场景。缺点:如果任务提交速度远大于处理速度,队列可能会无限增长,导致内存溢出。ExecutorService executor = Executors.newFixedThreadPool(10);for (int i = 0; i lt; 100; i ) { executor.execute(() -gt; { try { Thread.sleep(100); // 模拟运行操作 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(quot;线程: quot; Thread.currentThread().getName()); });}executor.shutdown(); // 注意关闭线程池登录后复制Executors.newCachedThreadPool()
创建一个可缓存的线程池。线程池的大小不固定的,可以根据任务的需要动态调整。如果没有空闲线程,则创建新的线程;如果线程空闲超过一定阈值(默认60秒),则默认被恢复。优点:可以充分利用系统资源,处理大量短期任务。缺点:如果任务提交速度过快,可能会创建大量的线程,导致CPU占用率过高,甚至OOM。不太适合长时间运行且任务量持续出现多个场景。
ExecutorService executor = Executors.newCachedThreadPool();for (int i = 0; i lt; 100; i ) { Final int taskNum = i; executor.execute(() -gt; { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(quot;线程: quot;Thread.currentThread().getName() quot;, Task: quot;taskNum); });}executor.shutdown();登录后复制Executors.newSingleThreadExecutor()
创建一个单线程的Executor。它保证所有的任务都按照提交的顺序依次执行。优点:保证任务的顺序执行,避免出现问题。缺点: ExecutorService executor = Executors.newSingleThreadExecutor();for (int i = 0; i lt; 10; i ) { Final int taskNum = i; executor.execute(() -gt; { System.out.println(quot;Thread: quot; Thread.currentThread().getName() quot;, Task: quot; taskNum); });}executor.shutdown();登录后复制Executors.newScheduledThreadPool(int corePoolSize)
创建一个可以执行延迟任务或定时任务的线程池。优点:可以方便地执行定时任务。缺点:相对复杂,需要仔细配置参数。
ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);//延迟1秒后执行executor.schedule(() -gt; { System.out.println(quot;延迟执行的任务.quot;);}, 1, TimeUnit.SECONDS);//每隔2秒执行一次executor.scheduleAtFixedRate(() -gt; { System.out.println(quot;周期性任务执行.quot;);}, 0, 2, TimeUnit.SECONDS);//注意:ScheduledExecutorService 通常需要手动关闭,否则程序可能无法退出// executor.shutdown(); //在适当的时候关闭登录后复制如何选择合适的Executor?
选择合适的Executor根据具体的应用场景而定。例如对于,CPU密集型任务,可以考虑使用newFixedThreadPool,线程数量设置为CPU核心数 1。对于IO密集型任务,可以使用newCachedThreadPool,让线程池根据需要动态调整大小。如果需要保证任务的顺序执行,可以使用newSingleThreadExecutor。如果需要执行定时任务,可以使用newScheduled ThreadPool。为什么不推荐使用Executors直接创建线程池?
阿里巴巴Java开发手册中建议不要使用Executors创建因为线程池,而是通过ThreadPoolExecutor的方法构造来创建。这就是Executor提供的线程池在某些情况下可能会导致OOM。例如,newFixedThreadPool和newSingleThreadExecutor的LinkedBlockingQueue默认长度是Integer.MAX_VALUE,可能会占用大量的请求,导致OOM。但是newCachedThreadPool虽然可以动态创建线程,但如果不控制好线程的数量,也可能会导致OOM。ThreadPoolExecutor的参数详解
ThreadPoolExecutor是线程创建池的核心类。
它的构造方法如下:public ThreadPoolExecutor(int corePoolSize, int maxPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueuelt;Runnablegt; workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) 登录后复制 corePoolSize: 核心线程数。线程池中始终保持线程数量,即使它们是空闲的。maximumPoolSize:最大线程数。线程池中允许的最大线程数量。keepAliveTime:线程空闲时间。当线程池中的线程数量超过corePoolSize时,多余的空闲线程的最多时间。单位:keepAliveTime的时间单位。workQueue:任务队列。用于保存等待执行的任务。常见的队列类型有LinkedBlockingQueue、ArrayBlockingQueue、SynchronousQueue等。threadFactory:线程工厂。用于新创建的线程。handler: 拒绝策略。当任务队列已满且线程池中的线程数量达到maximumPoolSize时,新提交的任务将被拒绝。常见的拒绝策略有AbortPolicy(发送异常)、CallerRunsPolicy(由调用者线程执行)、Discard Policy(直接丢弃)、DiscardOldestPolicy(丢弃队列中最老的任务)。如何优雅地关闭线程池?
关闭线程池通常有两种方式:shutdown()和shutdownNow()。shutdown():平滑关闭线程池,不再接受新的任务,但会等待所有已提交的任务执行结束。shutdownNow():立即关闭线程池,尝试停止所有正在执行的任务,并返回等待执行的任务列表。
建议使用shutdown()方法,给线程池一个缓慢关闭的机会。在关闭线程池后,需要调用awaitTermination()方法等待所有任务执行结束。
ExecutorService executor = Executors.newFixedThreadPool(10);//提交任务...executor.shutdown(); //拒绝接受新的任务try { if (!executor.awaitTermination(60, TimeUnit.SECONDS)) { executor.shutdownNow(); //超时后强制关闭 }} catch (InterruptedException e) { executor.shutdownNow(); Thread.currentThread().interrupt();}登录后复制
以上就是java中的executor是什么线程池Executor的4种创建方式的详细内容,更多请关注乐哥常识网其他相关文章!