优雅的创建线程池

Java提供了一个Executors类来帮助创建线程池,但是如果想要创建一个优雅的线程池,需要考虑以下几个方面:

  1. 池大小

线程池的大小需要根据任务的类型和运行环境来确定。通常,线程池的大小应该设置为处理器的数量加上1或2。

  1. 线程池的类型

Java提供了几种线程池类型,每种类型都有不同的特点,例如Executors.newFixedThreadPool()用于创建指定大小的线程池,Executors.newCachedThreadPool()用于创建自动调整大小的线程池。选择合适的线程池类型可以提高效率和性能。

  1. 任务队列

线程池中的任务队列应该能够处理线程池大小以外的任务,因此需要选择适当的队列类型(例如LinkedBlockingQueue或PriorityBlockingQueue)。

  1. 线程池的生命周期

线程池的生命周期可以通过实现ThreadFactory接口来控制。ThreadFactory可以定制线程的属性(例如线程名称、线程是否为后台线程等),也可以在线程创建和销毁时执行一些处理。

基于上述要点,可以编写以下优雅的线程池:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.LinkedBlockingQueue;

public class MyThreadPool {
    private ExecutorService executorService;

    public MyThreadPool(int poolSize) {
        ThreadFactory threadFactory = new ThreadFactory() {
            private int threadCount = 0;

            public Thread newThread(Runnable r) {
                threadCount++;
                Thread t = new Thread(r, "MyThreadPool-" + threadCount);
                t.setDaemon(true);
                return t;
            }
        };

        this.executorService = Executors.newFixedThreadPool(poolSize, threadFactory);
    }

    public void submitTask(Runnable task) {
        executorService.submit(task);
    }

    public void shutdown() {
        try {
            executorService.shutdown();
            executorService.awaitTermination(5, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            System.out.println("MyThreadPool shutdown interrupted: " + e.getMessage());
        } finally {
            executorService.shutdownNow();
        }
    }
}

在这个例子中,创建了一个固定大小的线程池,每个线程都是一个后台线程,并且使用了ThreadFactory在线程创建和销毁时执行一些处理(即设定线程名称)。在线程池关闭时,使用了awaitTermination来等待正在执行的任务完成,并且使用shutdownNow来强制停止线程池。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Go语言中,可以通过使用goroutine和channel来实现线程池。下面是一个优雅实现线程池的示例代码: ```go package main import ( "fmt" "sync" ) type ThreadPool struct { workerCount int taskQueue chan func() wg sync.WaitGroup } func NewThreadPool(workerCount int) *ThreadPool { tp := &ThreadPool{ workerCount: workerCount, taskQueue: make(chan func()), } tp.start() return tp } func (tp *ThreadPool) start() { for i := 0; i < tp.workerCount; i++ { go func() { for task := range tp.taskQueue { task() tp.wg.Done() } }() } } func (tp *ThreadPool) AddTask(task func()) { tp.wg.Add(1) tp.taskQueue <- task } func (tp *ThreadPool) Wait() { tp.wg.Wait() } func main() { // 创建线程池,指定线程数量为5 pool := NewThreadPool(5) // 添加任务到线程池 for i := 0; i < 10; i++ { taskID := i pool.AddTask(func() { fmt.Printf("Task %d is running\n", taskID) }) } // 等待所有任务完成 pool.Wait() } ``` 在上面的代码中,首先定义了一个`ThreadPool`结构体,包含了`workerCount`表示线程数量和`taskQueue`表示任务队列。`NewThreadPool`函数用于创建一个新的线程池,同时启动对应数量的goroutine来处理任务队列中的任务。 线程池通过`AddTask`方法添加任务,任务以函数的形式传入。`Wait`方法用于等待所有任务完成,使用了`sync.WaitGroup`来实现。 在`main`函数中,创建了一个线程池并添加了10个任务。每个任务都会打印自己的ID。 通过这种方式,可以灵活控制并发任务的数量,并且可以重复使用线程池来处理多个任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值