线程池的使用

线程池使用方法整理

ALL IN ONE

package multiThread.ThreadPool;

import java.util.concurrent.*;

public class Test {
    public static void main(String[] args) {
        // 使用线程池的方式有两种 
        // 一般不使用Executors 创建线程池,因为其内部使用的是无界的阻塞队列,容易造成OOM
        // 方式1 通过Executors工具类创建线程池
        // 1.1 创建固定大小的线程池
        ExecutorService service = Executors.newFixedThreadPool(3);
        service.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("固定大小线程池执行任务 "+Thread.currentThread().getName());
            }
        });
        // 1.2 创建单线程的线程池
        ExecutorService service1 = Executors.newSingleThreadExecutor();
        service1.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("单线程线程池执行任务 "+Thread.currentThread().getName());
            }
        });
        // 1.3 创建可缓存的线程池
        ExecutorService service2 = Executors.newCachedThreadPool();
        service2.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("可缓存线程池执行任务 "+Thread.currentThread().getName());
            }
        });
        // 1.4 创建可调度的线程池
        ScheduledExecutorService service3 = Executors.newScheduledThreadPool(2);
        Runnable task = () -> {
            System.out.println("Task executed at: " + System.currentTimeMillis());
        };

        // 以固定的时间间隔(2 秒)执行任务
        service3.scheduleAtFixedRate(task, 0, 2, TimeUnit.SECONDS);

        // 等待一段时间,然后关闭线程池
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        service3.shutdown();

        // 方式2 通过ThreadPoolExecutor创建线程池
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                2,
                5,
                1,
                TimeUnit.SECONDS,
                new java.util.concurrent.ArrayBlockingQueue<>(10)

        );
        for (int i = 0; i < 10; i++) {
            // 通过execute方法提交任务
            int finalI = i;
            threadPoolExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("线程池执行任务 "+ finalI +" "+Thread.currentThread().getName());
                }
            });
        }



    }
}

如何使用ThreadPoolExecutor

ThreadPoolExecutor 是 Java 中用于创建和管理线程池的类,它提供了灵活的线程管理和任务调度机制。下面是一个简单的例子,演示如何使用 ThreadPoolExecutor


import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolExample {
    public static void main(String[] args) {
        // 创建一个 ThreadPoolExecutor
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            2, // 核心线程数
            5, // 最大线程数
            1, // 线程空闲时间
            TimeUnit.SECONDS, // 空闲时间单位
            new java.util.concurrent.ArrayBlockingQueue<>(10) // 阻塞队列
        );
        
        // 提交任务给线程池
        for (int i = 0; i < 20; i++) {
            int finalI = i;
            executor.submit(() -> {
                System.out.println("Task " + finalI + " is running in thread " + Thread.currentThread().getName());
            });
        }
        
        // 关闭线程池
        executor.shutdown();
    }
}

在这个例子中,我们创建了一个 ThreadPoolExecutor 实例,并设置了核心线程数、最大线程数、线程空闲时间和阻塞队列等参数。然后,我们通过 executor.submit() 方法提交了一些任务给线程池执行。最后,通过 executor.shutdown() 方法关闭线程池。

ThreadPoolExecutor 还有其他很多配置选项和方法,可以根据需求进行调整,例如设置拒绝策略、预启动核心线程、设置线程工厂等。请根据具体的应用场景来选择适当的参数和方法。

ThreadPoolExecutor 的submit 和 execute 方法区别

ThreadPoolExecutor 类提供了 submit() 方法和 execute() 方法,用于提交任务给线程池执行。它们在功能上有些许区别:

submit() 方法

  • submit() 方法可以接受 RunnableCallable 任务,并返回一个 Future 对象,通过 Future 对象可以获取任务的执行结果或取消任务。
  • submit() 方法的返回值是 Future 类型,可以通过调用 Future.get() 方法来获取任务的执行结果,或者使用 Future.cancel() 方法来取消任务。
  • submit() 方法还可以接受一个泛型参数,用于指定任务返回的结果类型。

Future<?> future = executor.submit(() -> {
    // 任务逻辑
});

execute() 方法:

  • execute() 方法只能接受 Runnable 任务,它没有返回值,因此无法获取任务的执行结果。
  • execute() 方法更适用于只关心任务的执行而不关心结果的情况。
executor.execute(() -> {
    // 任务逻辑
});

在大多数情况下,如果你关心任务的执行结果,需要等待任务完成并获取结果,就应该使用 submit() 方法。如果你只需要提交一个简单的任务给线程池执行,而不需要获取任务的执行结果,可以使用 execute() 方法。

posted @   末日旅行家  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示