【多线程案例】线程池的应用及实现

文章目录

    • 1. 什么是线程池?
    • 2. 线程池的应用
    • 3. 自己实现线程池

1. 什么是线程池?

线程池就相当于一个池子,里面有很多的创建好的线程,可以进行统一的管理。当我们使用线程的时候,直接从里面调取,而不用在频繁的创建与销毁。
线程池的优点:

  1. 降低了线程创建销毁的开销:不用频繁的创建销毁线程,减少了资源 的开销;
  2. 提高系统的稳定性:线程池中的线程是有限的的,避免了创建了大量线
    程,造成系统崩溃;
  3. 提高资源的利用率:线程池能够合理的分配系统资源(CPU时间,内存等),提高资源的利用率;
  4. 方便管理线程:线程池中的线程可以统一进行管理,方便创建,暂停,启动,销毁等操作;
  5. 提高响应速度:当有任务来后,不需要在创建线程,只需要分配一个线程,速度更快;

2. 线程池的应用

Java标准库中含有线程池,我们可以直接使用。

例如:

    public static void main(String[] args) {
        ExecutorService service = Executors.newFixedThreadPool(4);
        service.submit(() -> {
        System.out.println(Thread.currentThread().getName()  + " hello");
        });
    }
  • Executors.newFixedThreadPool(4)可以创建一个含有四个线程的线程池,返回值类型为ExecutorService;
  • submit是ExecutorService类中的一个重要方法,可以将一个任务放到线程池中。

当然并不止这一种线程池的创建,还有:

newFixedThreadPool: 创建固定线程数的线程池
newCachedThreadPool: 创建线程数目动态增长的线程池.
newSingleThreadExecutor: 创建只包含单个线程的线程池.
newScheduledThreadPool: 设定 延迟时间后执行命令,或者定期执行命令. 是进阶版的 Timer.

上面有一个细节,线程池的创建并不是直接new一个,而是通过Executors调用。Executors本质是ThreadPoolExecutor类的封装,是一个工厂模式,调用起来不用传各种参,更加简单。
如果我们直接new:
【多线程案例】线程池的应用及实现_第1张图片

【多线程案例】线程池的应用及实现_第2张图片
【多线程案例】线程池的应用及实现_第3张图片
【多线程案例】线程池的应用及实现_第4张图片
会发现非常的麻烦,但是我们可以很直观的知道线程池的结构使用。

3. 自己实现线程池

同前面定时器一样,要自己实现一个线程池,实现前我们要知道线程池的构造:

  1. 核心操作为 submit, 将任务加入线程池中
  2. 使用 Worker 类描述一个工作线程. 使用 Runnable 描述一个任务.
  3. 使用一个 BlockingQueue 组织所有的任务 每个 worker 线程要做的事情:
  4. 不停的从 BlockingQueue 中取任务并执行. 指定一下线程池中的最大线程数
  5. maxWorkerCount; 当当前线程数超过这个最大值时, 就不再新增 线程了.

代码:

class MyThreadPool{
    //堵塞循环队列,存放要执行的任务
    BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
    //模拟线程池的submit方法
    public void submit(Runnable runnable) throws InterruptedException {
        //每次调用此方法,在队列放入一个任务
        queue.put(runnable);
    }
    //线程池,n为线程个数
    public MyThreadPool(int n){
        for (int i = 0; i < n; i++) {
            Thread t = new Thread(() -> {
                //n个线程不停的循环,执行任务下
                while(true){
                    try {
                        Runnable runnable = queue.take();
                        runnable.run();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            t.start();
        }
    }
}
public class Test2 {

    public static void main(String[] args) throws InterruptedException {
        MyThreadPool myThreadPool = new MyThreadPool(4);
        for (int i = 0; i < 10; i++) {
            myThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + " hello!");
                }
            });
        }

    }
}

运行结果:
【多线程案例】线程池的应用及实现_第5张图片

你可能感兴趣的:(Java多线程编程,java,线程安全,线程池)