Java线程池例子详解编程语言
2023-06-13 09:20:28 时间
在做很多高并发应用的时候,单线程的瓶颈已经满足不了我们的需求,此时使用多线程来提高处理速度已经是比较常规的方案了。在使用多线程的时候,我们可以使用线程池来管理我们的线程,至于使用线程池的优点就不多说了。
对于多线程的线程安全处理,这个也非常重要,有些同学还是要多补补课。
Java线程池说起来也简单,简单说下继承关系:
ThreadPoolExecutor extends AbstractExecutorService implements ExecutorService extends Executor
还有一个支持延时执行线程和可以重复执行线程的实现类:
ScheduledThreadPoolExecutor extends ThreadPoolExecutor implements ScheduledExecutorService
大家把这些类中的相关方法弄清楚,使用线程池就不在话下了。其实弄清楚里面各个方法的功能也就够了。
最重要的还是在实践中总结经验,企业需要的是能实际解决问题的人。
下面是我写的一个例子,包括3个Java文件,分别是:
ExecutorServiceFactory.java
ExecutorProcessPool.java
ExecutorTest.java
下面贴出代码:
1、ExecutorServiceFactory.java
package com.test.threadpool; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger;
* @author SHANHY([email protected]) * @date 2015年12月4日 public class ExecutorServiceFactory { private static ExecutorServiceFactory executorFactory = new ExecutorServiceFactory(); /** * 定时任务线程池 private ExecutorService executors; private ExecutorServiceFactory() { /** * 获取ExecutorServiceFactory * @return public static ExecutorServiceFactory getInstance() { return executorFactory; /** * 创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。 * @return public ExecutorService createScheduledThreadPool() { // CPU个数 int availableProcessors = Runtime.getRuntime().availableProcessors(); // 创建 executors = Executors.newScheduledThreadPool(availableProcessors * 10, getThreadFactory()); return executors; /** * 创建一个使用单个 worker 线程的 * Executor,以无界队列方式来运行该线程。(注意,如果因为在关闭前的执行期间出现失败而终止了此单个线程, * 那么如果需要,一个新线程将代替它执行后续的任务)。可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。与其他等效的 * newFixedThreadPool(1) 不同,可保证无需重新配置此方法所返回的执行程序即可使用其他的线程。 * @return public ExecutorService createSingleThreadExecutor() { // 创建 executors = Executors.newSingleThreadExecutor(getThreadFactory()); return executors; /** * 创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 * execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 * 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。注意,可以使用 ThreadPoolExecutor * 构造方法创建具有类似属性但细节不同(例如超时参数)的线程池。 * @return public ExecutorService createCachedThreadPool() { // 创建 executors = Executors.newCachedThreadPool(getThreadFactory()); return executors; /** * 创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。在任意点,在大多数 nThreads * 线程会处于处理任务的活动状态。如果在所有线程处于活动状态时提交附加任务 * ,则在有可用线程之前,附加任务将在队列中等待。如果在关闭前的执行期间由于失败而导致任何线程终止 * ,那么一个新线程将代替它执行后续的任务(如果需要)。在某个线程被显式地关闭之前,池中的线程将一直存在。 * @return public ExecutorService createFixedThreadPool(int count) { // 创建 executors = Executors.newFixedThreadPool(count, getThreadFactory()); return executors;
public Thread newThread(Runnable r) { SecurityManager s = System.getSecurityManager(); ThreadGroup group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); Thread t = new Thread(group, r); t.setName("任务线程 - " + sn.incrementAndGet()); return t; }
2、ExecutorProcessPool.java
package com.test.threadpool; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; * 线程处理类 * @author SHANHY([email protected]) * @date 2015年12月4日 public class ExecutorProcessPool { private ExecutorService executor; private static ExecutorProcessPool pool = new ExecutorProcessPool(); private final int threadMax = 10; private ExecutorProcessPool() { System.out.println("threadMax " + threadMax); executor = ExecutorServiceFactory.getInstance().createFixedThreadPool(threadMax); public static ExecutorProcessPool getInstance() { return pool; /** * 关闭线程池,这里要说明的是:调用关闭线程池方法后,线程池会执行完队列中的所有任务才退出 * @author SHANHY * @date 2015年12月4日 public void shutdown(){ executor.shutdown(); /** * 提交任务到线程池,可以接收线程返回值 * @param task * @return * @author SHANHY * @date 2015年12月4日 public Future ? submit(Runnable task) { return executor.submit(task); /** * 提交任务到线程池,可以接收线程返回值 * @param task * @return * @author SHANHY * @date 2015年12月4日 public Future ? submit(Callable ? task) { return executor.submit(task); /** * 直接提交任务到线程池,无返回值 * @param task * @author SHANHY * @date 2015年12月4日 public void execute(Runnable task){ executor.execute(task); }
3、ExecutorTest.java
package com.test.threadpool; import java.util.concurrent.Callable; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; * 测试类 * @author SHANHY([email protected]) * @date 2015年12月4日 public class ExecutorTest { public static void main(String[] args) { ExecutorProcessPool pool = ExecutorProcessPool.getInstance(); for (int i = 0; i 200; i++) { Future ? future = pool.submit(new ExcuteTask1(i+"")); // try { // 如果接收线程返回值,future.get() 会阻塞,如果这样写就是一个线程一个线程执行。所以非特殊情况不建议使用接收返回值的。 // System.out.println(future.get()); // } catch (Exception e) { // e.printStackTrace(); // } for (int i = 0; i 200; i++) { pool.execute(new ExcuteTask2(i+"")); //关闭线程池,如果是需要长期运行的线程池,不用调用该方法。 //监听程序退出的时候最好执行一下。 pool.shutdown(); /** * 执行任务1,实现Callable方式 * @author SHANHY([email protected]) * @date 2015年12月4日 static class ExcuteTask1 implements Callable String { private String taskName; public ExcuteTask1(String taskName) { this.taskName = taskName; @Override public String call() throws Exception { try { // Java 6/7最佳的休眠方法为TimeUnit.MILLISECONDS.sleep(100); // 最好不要用 Thread.sleep(100); TimeUnit.MILLISECONDS.sleep((int)(Math.random() * 1000));// 1000毫秒以内的随机数,模拟业务逻辑处理 } catch (Exception e) { e.printStackTrace(); System.out.println("-------------这里执行业务逻辑,Callable TaskName = " + taskName + "-------------"); return " 线程返回值,Callable TaskName = " + taskName + " "; /** * 执行任务2,实现Runable方式 * @author SHANHY([email protected]) * @date 2015年12月4日 static class ExcuteTask2 implements Runnable { private String taskName; public ExcuteTask2(String taskName) { this.taskName = taskName; @Override public void run() { try { TimeUnit.MILLISECONDS.sleep((int)(Math.random() * 1000));// 1000毫秒以内的随机数,模拟业务逻辑处理 } catch (Exception e) { e.printStackTrace(); System.out.println("-------------这里执行业务逻辑,Runnable TaskName = " + taskName + "-------------"); }
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/10116.html
cjava相关文章
- java random函数原理_详解JAVA中Random()函数的用法
- java卸载 安装错误_Java卸载后无法重新安装 提示已安装过[通俗易懂]
- 手机版java编译器_Java编译器[通俗易懂]
- 用java实现笛卡尔积_Java实现笛卡尔积
- 【说站】Java用户线程是什么
- java创建线程池的几种方式_Java中的线程池
- 【Java】函数式编程与JUC编程问题?函数式编程如何解决线程安全问题?
- Java线程
- 从java到JavaScript(2):对比Java/Go/Swift/Rust看Dart
- Java线程优先级示例详解编程语言
- java countDownLatch 线程辅助类详解编程语言
- java多线程有几种实现方法线程之间如何同步详解编程语言
- Java学习笔记之二java标识符命名规范详解编程语言
- Java 多线程详解(三)——线程的同步编程语言
- java线程安全与共享资源详解编程语言
- Java关闭Socket来终止线程详解编程语言
- java 线程池线程忙碌且阻塞队列也满了时给一个拒接的详细报告详解编程语言
- java线程 公平锁 ReentrantLock(boolean fair)详解编程语言
- java 线程之concurrent中的常用工具 CyclicBarrier详解编程语言
- Java线程新特征——Java并发库详解编程语言
- Java多线程1:进程与线程概述详解编程语言
- Linux下Java线程编程之旅(linuxjava线程)
- MacOS下Java开发环境搭建指南(macos开发java)
- 锁Redis Java实现的过期锁保证线程安全性(redisjava过期)
- Java轻松连接并执行MySQL数据库操作(java执行mysql)
- Java并发编程示例(一):线程的创建和执行