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

Java多线程~什么是线程池?如何创建线程池?你可以自己实现一个线程池吗?

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

Java多线程~什么是线程池?如何创建线程池?你可以自己实现一个线程池吗?

目录

什么是线程池?

如何创建线程池?

普通创建

快捷创建

手动实现一个线程池


什么是线程池?

线程池是多线程案例中非常重要的一个部分,线程池的使用可以很好的减少每次启动、销毁线程的损耗.

在之前的学习中,接触过字符串常量池以及数据库连接池,根据之前的认识,池的作用就是缓存。

线程池,即初始化(new线程池对象的时候)就创建了一定数量的线程,这些创建的线程不断地从阻塞队列中取任务,相当于是消费者。其他线程(生产者)只需要不断提交任务到线程池中。

举个例子来解释线程池

线程池就相当于是一个快递公司,公司开始创建时有2个正式员工(即new线程池对象池创建的线程数),阻塞队列就是快递公司的仓库,这两个正式员工不断地从仓库中取出快递去送,送完之后再回来取其他快递去送,相当于整个过程中一直这两个正式员工一直存在,不能辞退(即这两个线程不能销毁,核心线程),这样就有效的减少了每次启动、销毁线程的损耗。

线程池的优势:线程的创建和销毁都是有一定的代价(性能的损耗),使用线程池就可以重复使用线程来执行多组任务(类似于缓存,起到线程复用的目的).

如何创建线程池?

普通创建

Java api文档中的构造方法

· corePoolSize:核心线程数,即newThreadPollExecutor对象时初始化创建的线程数

· maximumPoolSIze:线程池最大线程数(核心线程以及临时线程)

· keepAliveTime:临时线程允许的空闲时间

· unit:keepAliveTime的时间单位

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolExecutorDemo {
    public static void main(String[] args) {
        //创建一个线程池: 开了一个快递公司
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                5,
                10,
                60,
                TimeUnit.SECONDS,
                //一般不使用无边界的阻塞队列,因为内存有限
                new ArrayBlockingQueue<>(10000),
                //拒绝策略: 一般最多使用CallerRunsPolicy,或自己实现
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
        pool.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello");
            }
        });
    }
}

快捷创建

· newFixedThreadPool:创建固定线程数的线程池

· newSingleThreadExecutor:创建只包含单个线程的线程池

· newCachedThreadPool:创建线程数目动态增长的线程池

· newScheduledThreadPool:计划任务的线程池,相当于进阶版的定时器

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

public class ExecutorServiceDemo {
    public static void main(String[] args) {
        //固定大小的线程池
        ExecutorService fixed = Executors.newFixedThreadPool(4);
        //单线程池
        ExecutorService single = Executors.newSingleThreadExecutor();
        //缓存的线程池
        ExecutorService cached = Executors.newCachedThreadPool();
        //计划任务的线程池
        ExecutorService scheduled = Executors.newScheduledThreadPool(10);
    }
}

手动实现一个线程池

在自己实现的线程池中具体包含如下内容:

· 线程池的核心操作为execute,将任务加入线程池中

· 使用阻塞队列来组织所有的任务(使用的是底层为数组的阻塞队列)

· 在创建线程池时,需要初始化核心线程的数目以及阻塞队列的容量

· 利用for循环来使初始化的核心线程不断地从阻塞队列中取任务,如果阻塞队列为空就等待

具体实现代码如下

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;


public class MyThreadPool {
    //线程数: 员工的数量
    private int count;
    //阻塞队列: 仓库
    private BlockingQueue queue;
    public MyThreadPool(int count, int capacity) {
        this.count = count;
        queue = new ArrayBlockingQueue<>(capacity);
        //线程池创建,就创建线程来不断取任务并执行
        for (int i = 0; i < count; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    //不停地从仓库中取任务: 如果取不到就等待
                    while(true) {
                        try {
                            Runnable task = queue.take();
                            task.run();//执行任务
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        }
    }
    //提交任务
    public void execute(Runnable task) {
        try {
            queue.put(task);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/937570.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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