了解线程池以及它的优点:

什么是线程池?为什么要有线程池?

怎么实现一个最简单的线程池?(附代码)

线程池大小怎么确定?

如今随着CPU的更新迭代,随着用户需求的不断增长,并发编程的重要性日益增高,由于进程的创建和销毁开销太大了,多线程技术应运而生,作为一种轻量级的进程,线程的创建和销毁的开销比进程要小很多,因此多线程更适合于并发编程。但是由于用户需求的更加增长,线程的创建和销毁所需要开销同样不可忽视,为了解决这个问题,协程和线程池技术被开发出来。协程是更轻量级的线程,但是协程并未进入Java标准库,在这里就不多介绍。

线程池:将线程提前创建好,放到池子里,需要的时候直接从池子里获取,用完了之后又放回池子里。

线程池的优点:

最大的好处就是减少每次启动、销毁线程的损耗

  1. 降低资源消耗:重复利用已创建的线程来降低线程创建和销毁造成的开销。
  2. 提高响应速度:当任务到达时,可以不需要线程等待创建就可以立即执行。

标准库中的线程池

使用 Executors.newFixedThreadPool(10) 能创建出固定包含 10 个线程的线程池.

返回值类型为 ExecutorService

通过 ExecutorService.submit 可以注册一个任务到线程池中.

ExecutorService pool = Executors.newFixedThreadPool(10);

pool.submit(new Runnable() {

   @Override

   public void run() {

       System.out.println("hello");

  }

});

Executors 创建线程池的几种方式

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

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

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

newScheduledThreadPool: 设定延迟时间后执行命令,或者定期执行命令. 是进阶版的 Timer.

Executors 本质上是 ThreadPoolExecutor 类的封装.

实现一个最简单的线程池:

实现之前我们需要了解,线程池的核心操作是什么,需要其他什么操作?

1.注册任务交给线程池

2.使用一个优先级队列存放线程

3.线程不断取出任务并且立即执行

4.指定一下线程池中最大线程数量

import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
public class ThreadDemo {
    public static void main(String[] args) {
        MyThreadPool pool = new MyThreadPool(10);
        for (int i = 10; i < 1000; i++) {
            int n = i; //变量捕获
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello" + n);
                }
            });
        }

    }
};

class MyThreadPool {

    //创建一个保存任务的队列
    private BlockingDeque<Runnable> queue = new LinkedBlockingDeque<>();

    //n表示线程数量
    public MyThreadPool(int n) {
        for (int i = 0; i < n; i++) {
            //创建线程 ,取出任务立即执行
            Thread t1 = new Thread(() -> {
                while (true) {
                    try {
                        Runnable runnable = queue.take();
                        runnable.run();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
            t1.start();
        }
    }

    //注册任务交给线程池
    public void submit(Runnable runnable) {

        try {
            queue.put(runnable);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

}

线程池大小怎么确定?

没有一个确定的说法,推荐根据需求来~~

CPU密集型:这种任务主要需要CPU的调度,可以将线程数量设置为CPU核心数N+1

IO密集型:这种情况下CPU调度需求不高,所以CPU可以有更多时间来完成其他线程的任务,因此可以多配一些线程,推荐为2N

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值