线程池的简单介绍以及实现一个线程池

1、线程池存在的意义

线程存在的意义:使用进程来实现并发编程,造成资源浪费等,因此引入了线程,使用线程来实现并发编程,线程也叫“轻量级进程”,因为 创建、销毁、调度线程比创建、销毁、调度进程更高效;
但是当我们需要频繁的创建、销毁线程时,就会发现开销还是挺大的,因此我们引入了线程池;

2、什么是线程池?

线程池:顾名思义就是“存放线程的池子”;

3、线程池的使用

事先把线程创建好,放到“池”中,后面需要使用的时候直接从“池”里获取即可;如果线程使用完毕,接着放回“池”里面;

注意:从“池”中取出,放入线程比创建销毁线程更高效;因为前者是用户代码实现的,后者是操作系统内核完成的;


什么是操作系统内核?
内核是操作系统的内部核心程序,它向外部提供了对计算机设备的核心管理调用。我们将操作系统的代码分成2部分。内核所在的地址空间称作内核空间。而在内核以外的统称为外部管理程序,它们大部分是对外围设备的管理和界面操作。外部管理程序与用户进程所占据的地址空间称为外部空间。通常,一个程序会跨越两个空间。当执行到内核空间的一段代码时,我们称程序处于内核态,而当程序执行到外部空间代码时,我们称程序处于用户态;
概念有点抽象。举个例子:

去面馆吃饭,你正在吃面的时候突然 想喝冰红茶了,你有两种选择,第一种:自己到冰箱里面拿冰红茶,也就是上面说的“用户态”;第二种:让老板给你拿一瓶冰红茶送到你这里来;也就是上面说的“内核态”

相比于内核态来说,用户态的程序执行行为是可控的,就拿上述的面条例子来说,自己直接跑到冰箱拿冰红茶,就一定可以很快喝到冰红茶,但是如果让老板呢冰红茶送过来,什么时候可以喝到冰红茶就是不可预知的了,因为老板可能正在忙其他事情,等他忙完了才可以去拿冰红茶。因此,当使用系统调用,执行内核代码的时候,无法确定内核都要做哪些工作,整体的行为是不可控的;


2、java标准库中的线程池

 public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(10);//构造了有10个线程的线程池
        for (int i = 0; i < 100; i++) {
            int n = i;

            //将100个任务放到池子里,由池子里的线程来分配任务
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.print(n + " ");
                }
            });
        }
    }

注意:1、当前是往线程池里放了100个任务,这100个任务又是由10个线程来平均分配的(并非严格的平均分配,某一个线程多几个任务也是正常的);
2、我们会发现,main线程结束了,但是整个进程还是没结束,因为线程池里的线程都是前台线程,而前台线程会阻止进程结束
问题一:为什么要将i的值保存起来呢?
在这里插入图片描述
这里的i是main线程的局部变量(即i在主线程的栈上),但是随着主线程代码的结束,主线程的栈就销毁了,如果主线程销毁的时候当前任务的在线程池里还没排到,但是此时的i就已经销毁了,所以将i的值在当前run的栈上也拷贝了一份(即n)


3、认识一下不同的线程池:

在这里插入图片描述

4、认识一下线程池里的参数:

在这里插入图片描述


4、实现一个简单的线程池

class myThreadPool {
    private BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
    public myThreadPool(int k) {//创建线程,执行任务
        for(int i = 0;i < k;i++){
            Thread thread = new Thread( () -> {
                while(true){
                    try{
                        Runnable runnable = queue.take();//将任务从队列里拿出
                        runnable.run();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
            thread.start();
        }
    }

    public void submit(Runnable runnable) throws InterruptedException {
        queue.put(runnable);//将任务放到队列里面
    }
}
public class Test7 {
    public static void main(String[] args) throws InterruptedException {
        myThreadPool mythreadpool = new myThreadPool(10);//构造有10个线程的线程池

        for (int i = 0; i < 100; i++) {
            int n = i;
            mythreadpool.submit(new Runnable() {   //创建任务
                @Override
                public void run() {
                    System.out.println(n);
                }
            });

        }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值