Java多线程优化之线程池的使用方法

简介: Java多线程优化之线程池的使用方法

Java多线程优化之线程池

java标准库提供了ExecutorService接口表示线程池
创建这些线程池的方法都被封装到Executors这个类

一、FixedThreadPool

FixedThreadPool:线程数固定的线程池

public class ThreadPoolTest01 {
    public static void main(String[] args) {
        //创建一个线程数固定为6的线程池
        ExecutorService es = Executors.newFixedThreadPool(6);
        for (int i = 0; i < 6; i++) {
            es.submit(new Task01("start task" + i));
        }
        // 关闭线程池:
        es.shutdown();
    }

}
class Task01 implements Runnable{
    private final String name;

    public Task01(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println("start task " + name);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        System.out.println("end task " + name);
    }
}

运行后:

start task start task0
start task start task3
start task start task1
start task start task2
start task start task4
start task start task5
end task start task3
end task start task2
end task start task5
end task start task1
end task start task4
end task start task0

二、CachedThreadPool

CachedThreadPool:线程数根据任务动态调整的线程池

public class ThreadPoolTest02 {
    public static void main(String[] args) {
        ExecutorService es = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            es.submit(new Task02("start task" + i));
        }
        es.shutdown();
    }
}

class Task02 implements Runnable{
    private final String name;

    public Task02(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println("start task " + name);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        System.out.println("end task " + name);
    }
}

运行后:

start task start task0
start task start task1
start task start task2
start task start task3
start task start task4
end task start task1
end task start task0
end task start task3
end task start task4
end task start task2

如果想控制线程池的大小呢?首先看一下Executors.newCachedThreadPool()方法的源码:
MAX_VALUE = 0x7fffffff

/**
     * Creates a thread pool that creates new threads as needed, but
     * will reuse previously constructed threads when they are
     * available.  These pools will typically improve the performance
     * of programs that execute many short-lived asynchronous tasks.
     * Calls to {@code execute} will reuse previously constructed
     * threads if available. If no existing thread is available, a new
     * thread will be created and added to the pool. Threads that have
     * not been used for sixty seconds are terminated and removed from
     * the cache. Thus, a pool that remains idle for long enough will
     * not consume any resources. Note that pools with similar
     * properties but different details (for example, timeout parameters)
     * may be created using {@link ThreadPoolExecutor} constructors.
     *
     * @return the newly created thread pool
     */
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

可以这样实现:

int min = 5;
int max = 10;
ExecutorService es = new ThreadPoolExecutor(min, max,
        60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());

第一个参数min 表示这个线程池初始化了5个线程在里面工作
第二个参数max 表示如果5个线程不够用了,就会自动增加到最多10个线程
第三个参数60 结合第四个参数TimeUnit.SECONDS,表示经过60秒,多出来的线程还没有接到活儿,就会回收,最后保持池子里就5个
第四个参数TimeUnit.SECONDS 如上
第五个参数 new LinkedBlockingQueue() 用来放任务的集合

三、SingleThreadExecutor

SingleThreadExecutor:仅单线程执行的线程池
适用场景:任务需要定期反复执行

public class ThreadPoolTest03 {
    public static ScheduledExecutorService ses = Executors.newScheduledThreadPool(4);

    public static void main(String[] args) {
        //一秒后执行一次性任务
        ses.schedule(new Task03("one-time"), 1, TimeUnit.SECONDS);
        //2秒后开始执行定时任务,每3秒执行  
        //FixedRate是指任务总是以固定时间间隔触发,不管任务执行多长时间
        ses.scheduleAtFixedRate(new Task03("fixed-rate"), 2, 3, TimeUnit.SECONDS);
        //2秒后开始执行定时任务,以3秒为间隔执行 
        //FixedDelay是指,上一次任务执行完毕后,等待固定的时间间隔,再执行下一次任务
        ses.scheduleWithFixedDelay(new Task03("fixed-delay"),2,3,TimeUnit.SECONDS);
    }

}
class Task03 implements Runnable{
    private final String name;

    public Task03(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println("start task " + name);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        System.out.println("end task " + name);
    }
}

注意

线程池在程序执行完必须要关闭
1.调用shutdown()时,线程池的状态则立刻变成SHUTDOWN状态。此时,则不能再往线程池中添加任何任务,否则将会抛出RejectedExecutionException异常。
2.调用awaitTermination()则会等待指定的时间让线程池关闭。

目录
相关文章
|
2月前
|
消息中间件 缓存 Java
Spring框架优化:提高Java应用的性能与适应性
以上方法均旨在综合考虑Java Spring 应该程序设计原则, 数据库交互, 编码实践和系统架构布局等多角度因素, 旨在达到高效稳定运转目标同时也易于未来扩展.
137 8
|
2月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
178 1
|
2月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
204 1
|
3月前
|
Java Spring
如何优化Java异步任务的性能?
本文介绍了Java中四种异步任务实现方式:基础Thread、线程池、CompletableFuture及虚拟线程。涵盖多场景代码示例,展示从简单异步到复杂流程编排的演进,适用于不同版本与业务需求,助你掌握高效并发编程实践。(239字)
241 6
|
3月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
|
存储 监控 Java
Java多线程优化:提高线程池性能的技巧与实践
Java多线程优化:提高线程池性能的技巧与实践
526 1
|
设计模式 监控 Java
Java多线程基础-11:工厂模式及代码案例之线程池(一)
本文介绍了Java并发框架中的线程池工具,特别是`java.util.concurrent`包中的`Executors`和`ThreadPoolExecutor`类。线程池通过预先创建并管理一组线程,可以提高多线程任务的效率和响应速度,减少线程创建和销毁的开销。
880 2
|
Java 数据库
【Java多线程】对线程池的理解并模拟实现线程池
【Java多线程】对线程池的理解并模拟实现线程池
160 1
|
安全 算法 Java
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)(下)
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)
211 6
|
存储 安全 Java
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)(中)
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)
234 5