【JAVA】线程池

                                                    线程池

1、为什么要创建线程池?

(1)创建线程的开销很大

(2)预先建立好线程,有一个固定的预先线程数目,等待任务派发,任务完成后再回到线程池

 

2、线程池的参数

(1)corePoolSize  初始线程数量

(2)maximumPoolSize     最大允许的线程数量

(3)keepAliveTime     线程等待时间。超出初始线程数目的线程,如果超出等待时间将被回收

 

3、Java Executor Framework

先演示一个的简单的例子

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {

    public static void main(String[] args) {
        //设定一个初始线程数量与最大数量都为3的线程池
        ExecutorService service=Executors.newFixedThreadPool(3);
        //分配10个任务,这10个任务加入到一个先进先出的队列中,供线程完成
        //传入任务id,用来查看任务的完成情况
        for(int i=0;i<10;i++){
            service.submit(new WriteTask(i));
        }
        //主线程结束
        System.out.println("main thread finish");
    }
}

其中WriteTask为

public class WriteTask implements Runnable {

    private final int id;

    public WriteTask(int id) {
        this.id = id;
    }

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

运行结果

运行结果分析:

(1)刚开始时,有三个线程,用来完成编号为0 1 2的三个任务,这三个线程执行的顺序不定,因此会出现012的随机排列

(2)只有前三个任务完成时,接下来的三个任务才能开始(因为最多只有三个线程在执行)

(3)main函数结束的时候,这个程序并没有结束(main thread finish出现在最前面,接下来才是线程完成任务)

 

如果我想在10个任务全部完成的时候,退出这个线程池,该怎么操作?

依据:submit(Runnable r)会返回一个Future<?>,将其加入到一个list中,随后遍历这个list,使用Future<?>对象的get()方法,若线程执行完成,get()方***返回null(因为我用的Runnable,run()没有返回值),若未执行完成,则主线程一直处于等待状态。

具体代码

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Main {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //设定一个初始线程数量与最大数量都为3的线程池
        ExecutorService service=Executors.newFixedThreadPool(3);
        //记录任务完成情况的list
        List<Future<?>> list=new LinkedList<>();
        //分配10个任务,这10个任务加入到一个先进先出的队列中,供线程完成
        //传入任务id,用来查看任务的完成情况
        for(int i=0;i<10;i++){
            Future<?> task=service.submit(new WriteTask(i));
            list.add(task);
        }
        //主线程结束
        System.out.println("main thread finish");

        //判断10个任务是否完成
        for(Future<?> future:list){
            future.get();
        }
        System.out.print("所有的任务都已经完成");

        //退出线程池
        service.shutdown();
    }
}

此时输出为

可以看得出,10个任务确实已经完成了,最后退出这个线程池,程序最终也退出了

不过其实shutdown()方***等待,等待线程池完成当前已经分配的全部任务后,主线程才会执行shutdown()方法

 

全部评论

相关推荐

10-19 10:28
已编辑
成都理工大学 后端工程师
团孝子已上线feeling:面了很多家公司,能感受到目前只有小公司+外包喜欢问八股。大厂虽然也问八股,但是是从实习、项目中进行提问,并且大厂会问很深,面试官也会对你的回答进行思考➕追问,所以准备大厂面试前一定要备好相关资料。对于算法,我做的是codetop前100+力扣hot100+力扣高频150,面试中实感hot100就足够,基本上只要是hot100就秒答。对于项目和八股,我做的也是烂大街的星球项目,八股则是看小林和问ai,自己也写了很多技术博客和画了很多思维导图,并且自己也尝试用嘴巴说出来,不只停留于纸面。运气也很重要,必须要让面试官/HR看到简历才行,所以建议投递时间是下午两点。tl:第一岗位9.9&nbsp;投递9.10&nbsp;一面(一面评价:最近见过最强的大三,结束五分钟后约二面,都晚上九点了不下班吗)9.11&nbsp;二面(三道算法a出两道,反问评价:经验不够等横向,我实习生要啥经验)9.21挂(实习时间过短+其他原因,想要一年实习的,为什么不招个正职)第二岗位10.10投递10.11约面(主管打电话,说看到我之前投递记录了想要我挂qa职进去干后端,同意)10.14&nbsp;一面(无八股,主动说确实很强,意愿很强)10.16&nbsp;oc其余,友邦,东软,东华,惠择,用友oc已拒京东测开一面挂(投后端被测开捞)腾讯测试已拒(投后端被测开捞)ps:表扬惠择的主管面,没怎么问技术(可能是一面面试官沟通过了),全程一起讲大道理,解答了心中很多疑惑,也告诉我以面试官角度来看怎么选候选人,如果可以下次一定选惠择
HeaoDng:美团好像可以触发一面通
点赞 评论 收藏
分享
11-04 10:30
已编辑
门头沟学院 研发工程师
开心小狗🐶:“直接说答案”
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务