Java线程池的实现示例

最近在写Java程序的时候,接触到一些多线程方面的东西,用到了Java中的线程池。JDK中对线程池的支持比较完善,在java.util.concurrent包中,用ThreadPoolExecuter类表示一个线程池,同时还有一个Executor类扮演着线程池工厂的角色。例如:

 

 代码如下 复制代码
public static ExecutorService newFixedThreadPool(int nThreads)
public static ExecutorService newSingleThreadExecutor()
public static ExecutorService newCachedThreadPool()
...

这些工厂方法,从本质上,都是调用了ThreadPoolExecutor类的构造函数:

 

 代码如下 复制代码
public ThreadPoolExecutor(int corePoolSize,
                    int maximumPoolSize,
                    long keepAliveTime,
                    TimeUnit unit,
                    BlockingQueue<Runnable> workQueue,
                    ThreadFactory threadFactory,
                    RejectedExecutionHandler handler)

参数含义如下:

corePoolSize:线程池中应该保持的线程数量,即使线程空闲
maximumPoolSize:线程池中最大线程的数量
keepAliveTime:当线程数量大于corePoolSize时,指定空闲线程存在多久会被销毁
unit:keepAliveTime的单位
workQueue:任务队列,被提交但还没有执行
threadFactory:线程工厂
handler:拒绝策略

实现思路

从ThreadPoolExecutor的构造函数中,我们大概知道实现一个线程池需要哪些东西,如果完全按照构造函数中的参数来的话,太麻烦,有太多地方需要考虑,因此实现一个简单版的。

首先需要考虑线程池中存放多少线程。可以简单用一个变量来指定,并且这些线程要放在一个容器里,便于销毁,也便于知道他们的状态。
然后我们要考虑一个作为任务队列的容器。假如线程池中有5个线程,如果5个线程都处于工作状态的话,这时候送来的任务就需要放在任务队列中等待。
最后是线程池中工作线程的形式。工作线程在创建时开始就应该启动,其所做的工作主要是:从任务队列中取出任务-执行任务这样的无限循环。
工作线程的一种实现方式:

 

 代码如下 复制代码

class WorkerThread extends Thread {
    private Boolean isRunning = true;
   
    public void close() {
        isRunning = false;
    }

    public void run() {
        while (isRunning) {
            Runnable task = null;
            try {
                task = taskQueue.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            task.run();
        }
    }
}

WorkerThread是线程池的内部类,其中,taskQueue是任务队列,这里采用了BlockingQueue接口的一种实现,其put和take方法都是阻塞的。提交任务和销毁线程池如下:

 

 代码如下 复制代码

public void submit(Runnable task) {
    if (currentWorking() < limits) {
        WorkerThread worker = new WorkerThread();
        worker.start();
        workers.add(worker);
    }
    try {
        taskQueue.put(task);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public void destroy() {
    while (!taskQueue.isEmpty());
    for (WorkerThread worker : workers) {
        worker.close();
    }
}

完整代码在这里。

 代码如下 复制代码

import java.util.ArrayList;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * Created by rahul on 7/20/16.
 */
public class SimpleThreadPool {
    public static BlockingQueue<Integer> testQueue = new LinkedBlockingQueue<>();

    private int limits;
    private ArrayList<WorkerThread> workers;
    private BlockingQueue<Runnable> taskQueue;

    SimpleThreadPool(int nums) {
        limits = nums;
        workers = new ArrayList<>();
        taskQueue = new LinkedBlockingQueue<>();
    }

    private int currentWorking() {
        return workers.size();
    }

    public void submit(Runnable task) {
        if (currentWorking() < limits) {
            WorkerThread worker = new WorkerThread();
            worker.start();
            workers.add(worker);
        }
        try {
            taskQueue.put(task);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void destroy() {
        while (!taskQueue.isEmpty());
        for (WorkerThread worker : workers) {
            worker.close();
        }
    }

    class WorkerThread extends Thread {
        private Boolean isRunning = true;

        public void close() {
            isRunning = false;
        }

        public void run() {
            while (isRunning) {
                Runnable task = null;
                try {
                    task = taskQueue.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                task.run();
            }
        }
    }

    public static void main(String[] args) {
        SimpleThreadPool pool = new SimpleThreadPool(10);
        for (int i = 0; i < 100; ++i) {
            pool.submit(new test("Task " + i));
        }
        pool.destroy();
    }
}

class test implements Runnable {
    private String id;

    public test(String str) { id = str; }

    public void run() {
        try {
            System.out.println("Start process " + id);
            Thread.sleep(1000);
            System.out.println(id + " Completed!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

线程池看似简单,其实很复杂,因为如果真要到一个应用级别的话,要考虑的东西还有很多,例如何时该启动一个线程,何时线程应该中止与挂起,任务队列的阻塞与超时,任务拒绝策略,线程生命周期等。至于本文实现的线程池

时间: 2024-09-26 06:51:19

Java线程池的实现示例的相关文章

java线程池当其中一个线程算出结果,终止全部线程

问题描述 java线程池当其中一个线程算出结果,终止全部线程 业务逻辑: 一个大型社区,每一秒有上千人在提交留言,提交的留言将经过,上万条的正则表达式的过滤,没有匹配任何规则的,才保存到系统,否则提示用户,您录入的内容不合法. 我是这样想的,把这上万条正则表达式,拆分成2000条一组,开一个5个线程的线程池,每个线程将负责其中2000个规则的匹配. 每条留言提交时,将由这5个线程,去判断是否有匹配的规则,如果其中一个线程匹配到了规则,将结束其他4个线程的任务,返回给用户结果. 请问这种要怎么实现

Java 线程池详解_java

系统启动一个线程的成本是比较高的,因为它涉及到与操作系统的交互,使用线程池的好处是提高性能,当系统中包含大量并发的线程时,会导致系统性能剧烈下降,甚至导致JVM崩溃,而线程池的最大线程数参数可以控制系统中并发线程数不超过次数. 一.Executors 工厂类用来产生线程池,该工厂类包含以下几个静态工厂方法来创建对应的线程池.创建的线程池是一个ExecutorService对象,使用该对象的submit方法或者是execute方法执行相应的Runnable或者是Callable任务.线程池本身在不

Java线程池 ExecutorService

本篇主要涉及到的是java.util.concurrent包中的ExecutorService.ExecutorService就是Java中对线程池的实现. 一.ExecutorService介绍 ExecutorService是Java中对线程池定义的一个接口,它java.util.concurrent包中,在这个接口中定义了和后台任务执行相关的方法: Java API对ExecutorService接口的实现有两个,所以这两个即是Java线程池具体实现类(详细了解这两个实现类,点击这里):

Java线程池类ThreadPoolExecutor、ScheduledThreadPoolExecutor及Executors工厂类

Java中的线程池类有两个,分别是:ThreadPoolExecutor和ScheduledThreadPoolExecutor,这两个类都继承自ExecutorService.利用这两个类,可以创建各种不同的Java线程池,为了方便我们创建线程池,Java API提供了Executors工厂类来帮助我们创建各种各样的线程池.下面我们分别介绍一下这三个类. Java线程池ExecutorService继承树: 一.ThreadPoolExecutor ThreadPoolExecutor是Exe

Java 线程池的原理与实现

这几天主要是狂看源程序,在弥补了一些以前知识空白的同时,也学会了不少新的知识(比如 NIO),或者称为新技术吧.线程池就是其中之一,一提到线程,我们会想到以前<操作系统>的生产者与消费者,信号量,同步控制等等.一提到池,我们会想到数据库连接池,但是线程池又如何呢? 建议:在阅读本文前,先理一理同步的知识,特别是syncronized同步关键字的用法.关于我对同步的认识,要缘于大三年的一本书,书名好像是 Java 实战,这本书写得实在太妙了,真正的从理论到实践,从截图分析到.class字节码分析

Java线程池架构2-多线程调度器(ScheduledThreadPoolExecutor)

在前面介绍了java的多线程的基本原理信息:<Java线程池架构原理和源码解析(ThreadPoolExecutor)>,本文对这个java本身的线程池的调度器做一个简单扩展,如果还没读过上一篇文章,建议读一下,因为这是调度器的核心组件部分.   我们如果要用java默认的线程池来做调度器,一种选择就是Timer和TimerTask的结合,在以前的文章:<Timer与TimerTask的真正原理&使用介绍>中有明确的说明:一个Timer为一个单独的线程,虽然一个Timer可

Java线程池架构(二)多线程调度器

在前面介绍了java的多线程的基本原理信息:<Java线程池架构原理和源码解析>,本文对这个java本身的线程池的调度器做一个简单扩展,如果还没读过上一篇文章,建议读一下,因为这是调度器的核心组件部分. 我们如果要用java默认的线程池来做调度器,一种选择就是Timer和TimerTask的结合,在以前的文章:<Timer与 TimerTask的真正原理&使用介绍>中有明确的说明:一个Timer为一个单独的线程,虽然一个Timer可以调度多个 TimerTask,但是对于一

Java线程池入门

在做很多高并发应用的时候,单线程的瓶颈已经满足不了我们的需求,此时使用多线程来提高处理速度已经是比较常规的方案了.在使用多线程的时候,我们可以使用线程池来管理我们的线程,至于使用线程池的优点就不多说了. 对于多线程的线程安全处理,这个也非常重要,有些同学还是要多补补课. Java线程池说起来也简单,简单说下继承关系: ThreadPoolExecutor extends AbstractExecutorService implements ExecutorService extends Exec

Java线程池例子

在做很多高并发应用的时候,单线程的瓶颈已经满足不了我们的需求,此时使用多线程来提高处理速度已经是比较常规的方案了.在使用多线程的时候,我们可以使用线程池来管理我们的线程,至于使用线程池的优点就不多说了. 对于多线程的线程安全处理,这个也非常重要,有些同学还是要多补补课. Java线程池说起来也简单,简单说下继承关系: ThreadPoolExecutor extends AbstractExecutorService implements ExecutorService extends Exec