栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java线程池

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java线程池

为啥要有线程池

为了避免系统频繁地创建和销毁线程,我们可以让创建的线程复用。如果大家进行过数据库开发,那么对数据库连接池应该不会陌生。为了避免每次数据库查询都重新建立和销毁数据库连接,我们可以使用数据库连接池维护一些数据库连接,让它们长期保持在一个激活状态。当系统需要使用数据库时,并不是创建一个新的连接,而是从连接池中获得一个可用的连接即可。反之,当需要关闭连接时,并不真的把连接关闭,而是将这个连接“还”给连接池即可。这种方式可以节约不少创建和销毁对象的时间。

线程池也是类似的概念。在线程池中,总有那么几个活跃线程。当你需要使用线程时,可以从池子中随便拿一个空闲线程,当完成工作时,并不急着关闭线程,而是将这个线程退回到线程池中,方便其他人使用。

简而言之,在使用线程池后,创建线程变成了从线程池获得空闲线程,关闭线程变成了向线程池归还线程,如图所示。

JDK对线程池的支持

Executor框架提供了各种类型的线程池,主要有以下工厂方法:

 public static ExecutorService newFixedThreadPool(int nThreads)
 public static ExecutorService newSingleThreadExecutor()
 public static ExecutorService newCachedThreadPool()
 public static ExecutorService newSingleThreadScheduledExecutor()
 public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

以上工厂方法分别返回具有不同工作特性的线程池。这些线程池工厂方法的具体说明 如下。

  • newFixedThreadPool
    该方法返回一个固定线程数量的线程池。该线程池中的线程数量始终不变。当有一个新的任务提交时,线程池中若有空闲线程,则立即执
    行。若没有,则新的任务会被暂存在一个任务队列中,待有线程空闲时,便处理任务队列中的任务
public class ThreadPoolDemo {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) {
            executorService.execute(() -> {
                System.out.println("ThreadPoolDemo.main" + Thread.currentThread().getName());
                Sleep.sleep(1000);
            });
        }
    }
}

结果

ThreadPoolDemo.mainpool-1-thread-1
ThreadPoolDemo.mainpool-1-thread-2
ThreadPoolDemo.mainpool-1-thread-3
ThreadPoolDemo.mainpool-1-thread-4
ThreadPoolDemo.mainpool-1-thread-5
ThreadPoolDemo.mainpool-1-thread-2
ThreadPoolDemo.mainpool-1-thread-3
ThreadPoolDemo.mainpool-1-thread-5
ThreadPoolDemo.mainpool-1-thread-4
ThreadPoolDemo.mainpool-1-thread-1
  • newSingleThreadExecutor
    该方法返回一个只有一个线程的线程池。若多余一个任务被提交到该线程池,任务会被保存在一个任务队列中,待线程空闲,按先入先出的顺序执行队列中的任务
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {
            executorService.execute(() -> {
                System.out.println("ThreadPoolDemo.main" + Thread.currentThread().getName());
                Sleep.sleep(1000);
            });
        }
    }

结果:

ThreadPoolDemo.mainpool-1-thread-1
ThreadPoolDemo.mainpool-1-thread-1
ThreadPoolDemo.mainpool-1-thread-1
ThreadPoolDemo.mainpool-1-thread-1
ThreadPoolDemo.mainpool-1-thread-1
ThreadPoolDemo.mainpool-1-thread-1
ThreadPoolDemo.mainpool-1-thread-1
ThreadPoolDemo.mainpool-1-thread-1
ThreadPoolDemo.mainpool-1-thread-1
ThreadPoolDemo.mainpool-1-thread-1
  • newCachedThreadPool
    该方法返回一个可根据实际情况调整线程数量的线程池。线程池的线程数量不确定,但若有空闲线程可以复用,则会优先使用可复用的
    线程。若所有线程均在工作,又有新的任务提交,则会创建新的线程处理任务。所有线程在当前任务执行完毕后,将返回线程池进行复用。
 public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            executorService.execute(() -> {
                System.out.println("ThreadPoolDemo.main" + Thread.currentThread().getName());
                Sleep.sleep(500);
            });
            Sleep.sleep(200);
        }
    }

结果:

ThreadPoolDemo.mainpool-1-thread-1
ThreadPoolDemo.mainpool-1-thread-2
ThreadPoolDemo.mainpool-1-thread-3
ThreadPoolDemo.mainpool-1-thread-1
ThreadPoolDemo.mainpool-1-thread-2
ThreadPoolDemo.mainpool-1-thread-3
ThreadPoolDemo.mainpool-1-thread-1
ThreadPoolDemo.mainpool-1-thread-2
ThreadPoolDemo.mainpool-1-thread-3
ThreadPoolDemo.mainpool-1-thread-1
  • newSingleThreadScheduledExecutor
    该方法返回一个ScheduledExecutorService对象,线程池大小为1.ScheduledExecutorService接口在ExecutorService接口之上扩展了在给定时间执行某任务的功能,如在某个固定的延时之后执行,或者周期性执行某个任务。
        ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        // for (int i = 0; i < 10; i++) {
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            System.out.println("ThreadPoolDemo.main" + Thread.currentThread().getName() + " : " + System.currentTimeMillis());
        }, 0, 2, TimeUnit.SECONDS);
        // 创建并执行在给定延迟后启用的一次性操作。
        // public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit);
        // 创建并执行在给定延迟后启用的一次性操作。有返回值
        // public  ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit)
        // 创建并执行一个周期性动作,该周期性动作在给定的初始延迟之后首先启用,然后在给定的周期之后启用;即执行将在{@code initialDelay}之后开始,然后是{@code initialDelay+period},然后是{@code initialDelay+ 2 period},以此类推。如果任务的任何执行遇到异常,则后续执行将被抑制。否则,任务只能通过取消或终止执行程序来终止。如果这个任务的执行时间超过了它的周期,那么后续的执行可能会延迟开始,但不会并发执行。
        // public ScheduledFuture scheduleAtFixedRate(Runnable command,long initialDelay, long period, TimeUnit unit);


  • newScheduledThreadPool
    该方法也返回一个ScheduledExecutorService对象,但该线程池可以指定线程数量。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/886042.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号