Java四种线程池

news/2024/8/26 17:15:14

线程池的好处

1、线程的创建需要消耗的,用完了马上就扔了比较可惜,所以把它缓存起来,以后还能再用;

2、可以根据实际情况调整线程池的大小,防止线程太多;

3、有些场合可以用线程池来做同步(比如多个线程使用同一文件系统时,可以用SingleThreadExecutor来保持同步);

可缓存(可变大小)的线程池 CachedThreadPool

这是一种很宽松的线程池,当任务来了之后,如果没有可用的线程那么就新建一个,如果有空闲的线程,则直接使用现有的线程。

可以根据实际的处理需求动态变化线程的数量。如果实际处理需求没那么多了,就会把部分线程回收掉。反之,如果实际处理需求又上来了,就会重新创建线程。

比如下面的代码,模拟每隔2秒才有一个新任务,而这个任务每次只需要1秒就能执行完:

public class CachedThreadPool {
    
    static Random random = new Random();
    static int taskId = 0;
    static ExecutorService service = Executors.newCachedThreadPool();

    public static void main(String[] args) {
        while(true) {
            service.execute(new MyThread());
            try {
                //新增任务速度
                Thread.sleep(new Long(2*1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    static class MyThread implements Runnable{
        @Override
        public void run() {
            System.out.println("thread " + Thread.currentThread().getName() + " is running for task:" + (taskId++));
            try {
                //任务线程执行所需时间
                Thread.sleep(new Long(1*1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
    }
}

这种情况下,线程池只需要一个线程就够用了:

thread pool-1-thread-1 is running for task:0
thread pool-1-thread-1 is running for task:1
thread pool-1-thread-1 is running for task:2
thread pool-1-thread-1 is running for task:3
thread pool-1-thread-1 is running for task:4
thread pool-1-thread-1 is running for task:5

如果把任务执行时间增加到3秒,则会产生3个线程:

thread pool-1-thread-1 is running for task:0
thread pool-1-thread-2 is running for task:1
thread pool-1-thread-3 is running for task:2
thread pool-1-thread-1 is running for task:3
thread pool-1-thread-2 is running for task:4
thread pool-1-thread-3 is running for task:5
thread pool-1-thread-1 is running for task:6
thread pool-1-thread-2 is running for task:7
thread pool-1-thread-3 is running for task:8
thread pool-1-thread-1 is running for task:9

如果刚开始新增任务速度很快,后来变慢了,之前新增的线程会被回收掉

public static void main(String[] args) {
        int i = 0;
        while(true) {
            service.execute(new MyThread());
            long sleep = i>=5 ? 2000 : 50;   #<---------------- 前五个任务新增得很快故意让线程池多创建任务,之后变慢,让增加速度比任务执行速度还慢
            try {
                //新增任务速度
                Thread.sleep(sleep);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            i++;
        }
    }
    
    static class MyThread implements Runnable{
        @Override
        public void run() {
            System.out.println("thread " + Thread.currentThread().getName() + " is running for task:" + (taskId++));
            try {
                //任务线程执行所需时间
                Thread.sleep(new Long(1*1000));  #<-------------------- 执行速度是1秒,新增速度的一半
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

输出结果如下:

thread pool-1-thread-1 is running for task:0
thread pool-1-thread-2 is running for task:1
thread pool-1-thread-3 is running for task:2
thread pool-1-thread-4 is running for task:3
thread pool-1-thread-5 is running for task:4
thread pool-1-thread-6 is running for task:5
thread pool-1-thread-6 is running for task:6
thread pool-1-thread-6 is running for task:7
thread pool-1-thread-6 is running for task:8
thread pool-1-thread-6 is running for task:9
thread pool-1-thread-6 is running for task:10
thread pool-1-thread-6 is running for task:11
thread pool-1-thread-6 is running for task:12
...

后面只有thread-6在跑了,打开jconsole,会发现其他的thread-1-threac-X已经不见了。

 

 

固定大小的线程池 FixedThreadPool

这个好理解了,我就这么几个线程,你任务再多也没用。

 

定时执行线程池 ScheduledThreadPool

定时任务线程池要注意的是,在线程资源稀缺的时候(就是线程数量设置的很小,比增加的定时任务还少,不够用),任务的执行时间会影响任务的执行周期。简单来说就是不要把线程数量设置的太少了。

单线程的线程池 SingleThreadExecutor

它创建单个工作者来执行任务,如果工作者线程异常退出了会重新创建一个来替换。它可以确保任务在队列中依次串行执行,例如FIFO、LIFO、优先级。另外固定大小的线程池还提供了大量同步机制,从而是一个任务写入到内存的结果对于后续的任务是可见的。

转载于:https://www.cnblogs.com/at0x7c00/p/7988316.html


http://www.niftyadmin.cn/n/1123764.html

相关文章

HDU-2896 病毒侵袭(AC自动姬)

病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 28243 Accepted Submission(s): 6538 Problem Description当太阳的光辉逐渐被月亮遮蔽&#xff0c;世界失去了光明&#xff0c;大地迎来最黑暗的时刻。…

Aruba无线网络学习(二)

说明&#xff1a;工作过程中接触到了Aruba无线网络设备&#xff0c;并在其网站上下载了技术文档。文档是英文的&#xff0c;看起来有一点费劲。只好一边翻译&#xff0c;一边学习&#xff0c;一边记笔记。水平有限&#xff0c;难免有错误的地方&#xff0c;请大家帮助指正。七、…

四种ABAP数据对象(转)

在ABAP/4中可以使用四种数据对象 1、内部数据对象 创建内部数据对象供在特定的程序中使用&#xff0c;在该程序之外无效&#xff0c;包括文字、常量、变量 &#xff08;1&#xff09;文字 文字是固定值&#xff0c;分为文本文字和数字文字。文本文字是单引号内的字母数字字符序…

Linux速成教程

2019独角兽企业重金招聘Python工程师标准>>> Linux操作系统最为有名的是它对初学者不友好&#xff01;当用户开始接触Linux会感觉到迷惑不解&#xff1a;"Linux凭什么得到广泛应用&#xff0c;还如此声名显赫&#xff1f;" 1.终端和shell 2.常见的使用Lin…

截取与分析日志文件的特定行数的操作

在进行操作系统和数据库系统管理时经常会遇到在日志文件中查找某个字符或者按照时间截取某个时间段的日志进行分析。今天早上就遇到一个MySQL数据库上的问题mysql数据库在0-3点的时候数据库会话连接tpscpu和iowait等都比平时大了许多。为了定位这个时间段内到底发生了那些慢查询…

如何在Linux中查看所有正在运行的进程

你可以使用ps命令。它能显示当前运行中进程的相关信息&#xff0c;包括进程的PID。Linux和UNIX都支持ps命令&#xff0c;显示所有运行中进程的相关信息。ps命令能提供一份当前进程的快照。如果你想状态可以自动刷新&#xff0c;可以使用top命令。 ps命令 输入下面的ps命令&…

WinXP上无法应用WinSrv2008的活动目录组策略的解决办法

去年7月份&#xff0c;做了一次活动目录升级项目&#xff0c;由于他们的环境比较早&#xff0c;两台DC都是Win2000。此次项目的目标就是将域升级到Win2008环境。在项目中碰到诸多困难&#xff0c;最终都一一解决&#xff0c;其中有个之前没有料想到的问题&#xff0c;我觉得有必…

批处理 :windows计划任务;复制;压缩文件夹 备份;

添加windows计划任务&#xff1a; echo off echo 正在启动计划任务服务... sc config Schedule START AUTO >nul sc start Schedule>nul cls SCHTASKS /Create /SC DAILY /TN his_update /TR D:\HYS-HIS\hys-orcl\his_main\his_main.exe /ST 23:23:23 /SD 2012/02/26 >…