前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ThreadPoolExecutor 类

ThreadPoolExecutor 类

作者头像
Qwe7
发布2022-08-07 08:31:15
2690
发布2022-08-07 08:31:15
举报
文章被收录于专栏:网络收集网络收集

ThreadPoolExecutor 类

实现了 ExecutorService 接口,是 java 开发常用的线程池类。位于 java.util.concurrent 包内,使用时需要进行导入。

创建线程池

  1. ThreadPoolExecutor 类在创建线程池时需要输入以下参数:
代码语言:javascript
复制
int corePoolSize = 2;                                                // 核心线程池大小
int maximumPoolSize = 4;                                             // 最大线程池大小
long keepAliveTime = 10;                                             // 空闲线程多久被销毁,0 表示永远不会
TimeUnit unit = TimeUnit.SECONDS;                                    // keepAliveTime 的单位
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);     // 任务队列
ThreadFactory threadFactory = new NameTreadFactory();                // 线程工厂接口,一般默认。
RejectedExecutionHandler handler = new MyIgnorePolicy();             // 拒绝策略,一般默认。

ThreadPoolExecutor service = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, 
unit, workQueue, threadFactory, handler);Copy to clipboardErrorCopied
  1. ThreadPoolExecutor 类还可以重写以下方法(默认为空实现):
代码语言:javascript
复制
ExecutorService service = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1)) {
    // 任务执行前被调用
    @Override 
    protected void beforeExecute(Thread t, Runnable r) {
        System.out.println("beforeExecute is called");
    }
    // 任务执行后被调用
    @Override 
    protected void afterExecute(Runnable r, Throwable t) {
        System.out.println("afterExecute is called");
    }
    // 线程池结束后被调用
    @Override
    protected void terminated() {
        System.out.println("terminated is called");
    }
};Copy to clipboardErrorCopied

获取线程池信息

代码语言:javascript
复制
service.getTaskCount();                 // 获取已经执行或正在执行的任务数
service.getCompletedTaskCount();        // 获取已经执行的任务数
service.getLargestPoolSize();           // 获取线程池曾经创建过的最大线程数
service.getPoolSize();                  // 获取线程池线程数
service.getActiveCount();               // 获取活跃线程数(正在执行任务的线程数)Copy to clipboardErrorCopied

提交任务

可以向线程池提交的任务有两种:Runnable 接口和 Callable 接口。

Runnable 接口

内部定义了 run 方法,没有返回值,不允许抛出异常。通过 execute 方法向线程池提交。

代码语言:javascript
复制
service.execute(new Runnable(){             
    System.out.println("new thread");
});Copy to clipboardErrorCopied
Callable 接口

内部定义了 call 方法,允许有返回值,允许抛出异常。通过 submit 方法向线程池提交,返回一个 Future 对象。

可以通过调用 Future 对象的 get 方法获得数据,在返回结果前 get 方法会阻塞。

代码语言:javascript
复制
Future<Integer> f = service.submit(new Callable(){            
    System.out.println("new thread");
    return 1;
});
System.out.println(f.get());Copy to clipboardErrorCopied

关闭线程池

代码语言:javascript
复制
service.shutdown();      // 线程池不再接受新的任务,线程池中已有任务执行完成后终止。
service.shutdownNow();   // 线程池不再接受新的任务并对所有线程执行 interrupt 操作,清空队列并终止。

boolean b = service.isShutdown();      // 返回线程池是否关闭:不再接受新任务。
boolean b = service.isTerminated();    // 返回线程池是否终止Copy to clipboardErrorCopied

ThreadPoolExecutor 类示例

代码语言:javascript
复制
public class ThreadPool {
    private static ExecutorService pool;
    public static void main( String[] args )
    {
        //自定义线程工厂
        pool = new ThreadPoolExecutor(2, 4, 1000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(5),
                new ThreadFactory() {
            public Thread newThread(Runnable r) {
                System.out.println("线程"+r.hashCode()+"创建");
                //线程命名
                Thread th = new Thread(r,"threadPool"+r.hashCode());
                return th;
            }
        }, new ThreadPoolExecutor.CallerRunsPolicy());

        for(int i=0;i<10;i++) {
            pool.execute(new ThreadTask());
        }    
    }
}

public class ThreadTask implements Runnable{    
    public void run() {
        //输出执行线程的名称
        System.out.println("ThreadName:"+Thread.currentThread().getName());
    }
}Copy to clipboardErrorCopied

Executors 类(不常用)

继承 ThreadPoolExecutor 类的线程池工厂类:提供 4 种工厂方法创建线程池。但该方法既不灵活也不安全,实际开发中很少使用。

代码语言:javascript
复制
// 单个线程的线程池
ExecutorService service = Executors.newSingleThreadExecutor();
// 指定数量的线程池
ExecutorService service = Executors.newFixedThreadExecutor(10); 
// 大小不限的线程池,60s 不使用会自动回收空闲线程。
ExecutorService service = Executors.newCacheThreadExecutor();
// 大小不限的线程池,可定时执行任务。
ExecutorService service = Executors.newScheduleThreadExecutor();Copy to clipboardErrorCopied

Executors 类示例

代码语言:javascript
复制
public class ThreadPoolTest {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) {
            executor.submit(() -> {
                System.out.println("thread id is: " + Thread.currentThread().getId());
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}

实现了 ExecutorService 接口,是 java 开发常用的线程池类。位于 java.util.concurrent 包内,使用时需要进行导入。

创建线程池

  1. ThreadPoolExecutor 类在创建线程池时需要输入以下参数:
代码语言:javascript
复制
int corePoolSize = 2;                                                // 核心线程池大小
int maximumPoolSize = 4;                                             // 最大线程池大小
long keepAliveTime = 10;                                             // 空闲线程多久被销毁,0 表示永远不会
TimeUnit unit = TimeUnit.SECONDS;                                    // keepAliveTime 的单位
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);     // 任务队列
ThreadFactory threadFactory = new NameTreadFactory();                // 线程工厂接口,一般默认。
RejectedExecutionHandler handler = new MyIgnorePolicy();             // 拒绝策略,一般默认。

ThreadPoolExecutor service = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, 
unit, workQueue, threadFactory, handler);Copy to clipboardErrorCopied
  1. ThreadPoolExecutor 类还可以重写以下方法(默认为空实现):
代码语言:javascript
复制
ExecutorService service = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1)) {
    // 任务执行前被调用
    @Override 
    protected void beforeExecute(Thread t, Runnable r) {
        System.out.println("beforeExecute is called");
    }
    // 任务执行后被调用
    @Override 
    protected void afterExecute(Runnable r, Throwable t) {
        System.out.println("afterExecute is called");
    }
    // 线程池结束后被调用
    @Override
    protected void terminated() {
        System.out.println("terminated is called");
    }
};Copy to clipboardErrorCopied

获取线程池信息

代码语言:javascript
复制
service.getTaskCount();                 // 获取已经执行或正在执行的任务数
service.getCompletedTaskCount();        // 获取已经执行的任务数
service.getLargestPoolSize();           // 获取线程池曾经创建过的最大线程数
service.getPoolSize();                  // 获取线程池线程数
service.getActiveCount();               // 获取活跃线程数(正在执行任务的线程数)Copy to clipboardErrorCopied

提交任务

可以向线程池提交的任务有两种:Runnable 接口和 Callable 接口。

Runnable 接口

内部定义了 run 方法,没有返回值,不允许抛出异常。通过 execute 方法向线程池提交。

代码语言:javascript
复制
service.execute(new Runnable(){             
    System.out.println("new thread");
});Copy to clipboardErrorCopied
Callable 接口

内部定义了 call 方法,允许有返回值,允许抛出异常。通过 submit 方法向线程池提交,返回一个 Future 对象。

可以通过调用 Future 对象的 get 方法获得数据,在返回结果前 get 方法会阻塞。

代码语言:javascript
复制
Future<Integer> f = service.submit(new Callable(){            
    System.out.println("new thread");
    return 1;
});
System.out.println(f.get());Copy to clipboardErrorCopied

关闭线程池

代码语言:javascript
复制
service.shutdown();      // 线程池不再接受新的任务,线程池中已有任务执行完成后终止。
service.shutdownNow();   // 线程池不再接受新的任务并对所有线程执行 interrupt 操作,清空队列并终止。

boolean b = service.isShutdown();      // 返回线程池是否关闭:不再接受新任务。
boolean b = service.isTerminated();    // 返回线程池是否终止Copy to clipboardErrorCopied

ThreadPoolExecutor 类示例

代码语言:javascript
复制
public class ThreadPool {
    private static ExecutorService pool;
    public static void main( String[] args )
    {
        //自定义线程工厂
        pool = new ThreadPoolExecutor(2, 4, 1000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(5),
                new ThreadFactory() {
            public Thread newThread(Runnable r) {
                System.out.println("线程"+r.hashCode()+"创建");
                //线程命名
                Thread th = new Thread(r,"threadPool"+r.hashCode());
                return th;
            }
        }, new ThreadPoolExecutor.CallerRunsPolicy());

        for(int i=0;i<10;i++) {
            pool.execute(new ThreadTask());
        }    
    }
}

public class ThreadTask implements Runnable{    
    public void run() {
        //输出执行线程的名称
        System.out.println("ThreadName:"+Thread.currentThread().getName());
    }
}Copy to clipboardErrorCopied

Executors 类(不常用)

继承 ThreadPoolExecutor 类的线程池工厂类:提供 4 种工厂方法创建线程池。但该方法既不灵活也不安全,实际开发中很少使用。

代码语言:javascript
复制
// 单个线程的线程池
ExecutorService service = Executors.newSingleThreadExecutor();
// 指定数量的线程池
ExecutorService service = Executors.newFixedThreadExecutor(10); 
// 大小不限的线程池,60s 不使用会自动回收空闲线程。
ExecutorService service = Executors.newCacheThreadExecutor();
// 大小不限的线程池,可定时执行任务。
ExecutorService service = Executors.newScheduleThreadExecutor();Copy to clipboardErrorCopied

Executors 类示例

代码语言:javascript
复制
public class ThreadPoolTest {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) {
            executor.submit(() -> {
                System.out.println("thread id is: " + Thread.currentThread().getId());
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ThreadPoolExecutor 类
    • 创建线程池
      • 获取线程池信息
        • 提交任务
          • Runnable 接口
          • Callable 接口
        • 关闭线程池
        • Executors 类(不常用)
          • 创建线程池
            • 获取线程池信息
              • 提交任务
                • Runnable 接口
                • Callable 接口
              • 关闭线程池
              • Executors 类(不常用)
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档