简述多线程

1 线程池

1.1 什么是线程池

线程池是一种多线程处理形式,处理过程中将任务添加到队列中,随着创建线程而开始自动执行任务。

注意点
1 任务一般是实现Runable接口的实例
2 与Thread创建线程不同,当我们用实现Runable接口的实例的任务时,我们需要将任务的对象添加到Thread中去。
3 线程池则不需要将任务添加到Thread中在thread.start()执行,用线程池创建的线程随着创建线程而自动执行任务。

下面截取部分代码说明Thread执行线程与线程池执行线程的区别:

1 Thread执行线程
在这里插入图片描述

2 线程池执行线程
在这里插入图片描述

1.2 为什么要使用线程池

线程池可以根据系统需求和硬件环境来灵活的控制线程的数量,且用线程池创建的线程方便管理和控制,提高系统运行效率,减轻系统的运行压力。

1.3 线程池运用场景

1 商品秒杀项目
2 12306抢票
3 网盘下载
4 …

2 线程池工作原理

2.1 线程池的组成

线程池由以下几部分组成
1 核心线程数(corePoolSize)(必需):默认状态下,会一直存活,但是当将 allowCoreThreadTimeout 设置为 true 时,核心线程也会超时回收。

2 最大线程数(maximumPoolSize)(必需0):线程池能容纳的最大活跃线程数,当活跃线程数达到该数值后,后续的新任务将会阻塞。

3 任务队列(workQueue)(必需):能容纳的最多阻塞线程数

4 设置闲时时长(keepAliveTime)(必需):线程闲置超时时长。如果超过该时长,非核心线程就会被回收。如果将 allowCoreThreadTimeout 设置为 true 时,核心线程也会超时回收。

5 参数时间单位(unit)(必需):指定 keepAliveTime 参数的时间单位。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)。

6 拒绝策略(handler)(不必需):当线程池中的线程已达到最大线程池容量时,外面的线程想要在进入线程池,线程池需要采取的方式

7 线程工厂(threadFactory)(可选):线程工厂。用于指定为线程池创建新线程的方式。

线程池结构如下

在这里插入图片描述

2.2 线程池工作原理

在这里插入图片描述

3 线程池使用

3.1 构造方法

public ThreadPoolExecutor(int corePoolSize, //核心线程数量
      int maximumPoolSize,//     最大线程数
      long keepAliveTime, //       最大空闲时间
      TimeUnit unit,         //        时间单位
      BlockingQueue<Runnable> workQueue,   //   任务队列
      ThreadFactory threadFactory,    // 线程工厂
      RejectedExecutionHandler handler  //  饱和处理机制
	) 

3.2创建线程池

public class ThreadPoolDemo {

    CountDownLatch countDownLatch = new CountDownLatch(MAX_TURN);
    public static final int SLEEP_GAP = 500;
    public static final int MAX_TURN = 5;

    //异步的执行目标类
    public static class TargetTask implements Runnable {
        CountDownLatch countDownLatch;
        static AtomicInteger taskNo = new AtomicInteger(1);
        protected String taskName;

        public TargetTask() {
            taskName = "task-" + taskNo.get();
            taskNo.incrementAndGet();
        }

        public TargetTask(CountDownLatch countDownLatch) {
            this();
            this.countDownLatch = countDownLatch;
        }

        public void run() {
            System.out.println("任务:" + taskName + " doing");

            try {
                Thread.sleep(SLEEP_GAP);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            System.out.println(taskName + " 运行结束.");
            countDownLatch.countDown();
        }

        @Override
        public String toString() {
            return "TargetTask{" + taskName + '}';
        }
    }

    //测试用例:只有一条线程的线程池
    @Test
    public void testSingleThreadExecutor() {
        ExecutorService pool = Executors.newSingleThreadExecutor();
        for (int i = 0; i < MAX_TURN; i++) {
            pool.execute(new TargetTask(countDownLatch));
        }

        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

//        //关闭线程池
        pool.shutdown();
    }

    //测试用例:只有3条线程固定大小的线程池
    @Test
    public void testNewFixedThreadPool() throws InterruptedException {
        ExecutorService pool = Executors.newFixedThreadPool(3);
        for (int i = 0; i < MAX_TURN; i++) {
            pool.execute(new TargetTask(countDownLatch));
        }

        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        //关闭线程池
        pool.shutdown();
    }

    /**
     * CachedThredPool:线程数没有限制
     * @throws InterruptedException
     */
    @Test
    public void testNewCachedThreadPool() throws InterruptedException {
        ExecutorService pool = Executors.newCachedThreadPool();
        for (int i = 0; i < MAX_TURN; i++) {
            pool.execute(new TargetTask(countDownLatch));
        }

        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        //关闭线程池
        pool.shutdown();
    }


    //测试用例:“可调度线程池”
    @Test
    public void testNewScheduledThreadPool() {
        ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(2);
        for (int i = 0; i < 2; i++) {
            scheduled.scheduleAtFixedRate(new TargetTask(countDownLatch),
                    0, 5000, TimeUnit.MILLISECONDS);
        }

        try {
            Thread.sleep(1000000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        //关闭线程池
        scheduled.shutdown();
    }


    @Test
    public void testThreadPoolExecutor() {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                2, //corePoolSize
                4, //maximumPoolSize
                100, //keepAliveTime
                TimeUnit.SECONDS, //unit
                new LinkedBlockingDeque<>(2), new ThreadPoolExecutor.CallerRunsPolicy());//workQueue

        for (int i = 0; i < 7; i++) {
            final int taskIndex = i;

            Runnable task = new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() +  "   taskIndex = " + taskIndex );
                    try {
                        Thread.sleep(10000);
//                        Thread.sleep(Long.MAX_VALUE);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };

            executor.execute(task);
        }
        while (true) {
            //每隔 1 秒,输出线程池的工作任务数量、总计的任务数量
            System.out.printf("- activeCount: %d - taskCount: %d\r\n", executor.getActiveCount(), executor.getTaskCount());
            ThreadUtil.sleepSeconds(1);
        }
    }

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值