专注Java教育14年 全国咨询/投诉热线:400-8080-105
动力节点LOGO图
始于2009,口口相传的Java黄埔军校
首页 学习攻略 Java学习 Java实现创建线程池

Java实现创建线程池

更新时间:2022-06-24 09:37:41 来源:动力节点 浏览1051次

Java实现创建线程池要怎么做?动力节点小编来告诉大家。线程池是可以“重用”执行任务 的池线程,这样每个线程可以执行多个任务。线程池是为您需要执行的每个任务创建新线程的替代方法。

与重用已创建的线程相比,创建新线程会带来性能开销。这就是为什么重用现有线程来执行任务比为每个任务创建一个新线程会导致更高的总吞吐量。

此外,使用线程池可以更轻松地控制一次有多少线程处于活动状态。每个线程都会消耗一定量的计算机资源,比如内存(RAM),所以如果你有太多线程同时处于活动状态,那么消耗的资源总量(比如RAM)可能会导致计算机变慢——例如,如果消耗了太多 RAM,以至于操作系统 (OS) 开始将 RAM 换出到磁盘。

线程池用例

线程池通常用于多线程服务器。通过网络到达服务器的每个连接都被包装为一个任务并传递到线程池。线程池中的线程将同时处理连接上的请求。稍后将详细介绍在 Java 中实现多线程服务器。

内置Java线程池

Java 在包中带有内置的线程池java.util.concurrent,因此您不必实现自己的线程池。您可以在我关于java.util.concurrent.ExecutorService的文本中阅读有关它的更多信息 。无论如何,了解线程池的实现仍然很有用。

Java线程池实现

这是一个简单的线程池实现。该实现使用 Java 5 附带 的标准Java BlockingQueue 。

导入 java.util.ArrayList;
导入 java.util.List;
导入 java.util.concurrent.ArrayBlockingQueue;
导入 java.util.concurrent.BlockingQueue;
公共类线程池 {

    私有阻塞队列任务队列=空;
    私有列表<PoolThreadRunnable> runnables = new ArrayList<>();
    私有布尔 isStopped = false;
    公共线程池(int noOfThreads,int maxNoOfTasks){
        taskQueue = new ArrayBlockingQueue(maxNoOfTasks);
        for(int i=0; i<noOfThreads; i++){
            PoolThreadRunnable poolThreadRunnable =
                    新的 PoolThreadRunnable(taskQueue);
            runnables.add(new PoolThreadRunnable(taskQueue));
        }
        for(PoolThreadRunnable runnable : runnables){
            新线程(可运行).start();
        }
    }
    公共同步无效执行(可运行任务)抛出异常{
        如果(this.isStopped)抛出
                new IllegalStateException("线程池已停止");

        this.taskQueue.offer(任务);
    }
    公共同步无效停止(){
        this.isStopped = true;
        for(PoolThreadRunnable runnable : runnables){
            runnable.doStop();
        }
    }
    公共同步无效 waitUntilAllTask​​sFinished() {
        而(this.taskQueue.size()> 0){
            尝试 {
                线程.sleep(1);
            } 捕捉(InterruptedException e){
                e.printStackTrace();
            }
        }
    }

}

下面是实现 Runnable 接口的 PoolThreadRunnable 类,因此它可以由 Java 线程执行:

导入 java.util.concurrent.BlockingQueue;
公共类 PoolThreadRunnable 实现 Runnable {
    私有线程线程 = null;
    私有阻塞队列任务队列=空;
    私有布尔 isStopped = false;
    公共 PoolThreadRunnable(BlockingQueue 队列){
        任务队列 = 队列;
    }
    公共无效运行(){
        this.thread = Thread.currentThread();
        而(!isStopped()){
            尝试{
                Runnable runnable = (Runnable) taskQueue.take();
                可运行的.run();
            } 捕捉(异常 e){
                //记录或以其他方式报告异常,
                //但保持池线程处于活动状态。
            }
        }
    }
    公共同步无效doStop(){
        isStopped = true;
        //从 dequeue() 调用中中断池线程。
        this.thread.interrupt();
    }
    公共同步布尔 isStopped(){
        返回已停止;
    }
}

最后是如何使用上面的 ThreadPool 的示例:

公共类 ThreadPoolMain {
    公共静态 void main(String[] args) 抛出异常 {
        线程池 threadPool = new ThreadPool(3, 10);
        for(int i=0; i<10; i++) {
            int taskNo = i;
            threadPool.execute(() -> {
                字符串消息 =
                        Thread.currentThread().getName()
                                + ": 任务" + taskNo ;
                System.out.println(消息);
            });
        }
        threadPool.waitUntilAllTask​​sFinished();
        线程池.stop();
    }
}

线程池实现由两部分组成。ThreadPool作为线程池的公共接口的类PoolThread,以及实现执行任务的线程的类。

为了执行一个任务,该方法ThreadPool.execute(Runnable r)以一个 Runnable实现作为参数被调用。内部Runnable在 阻塞队列中排队,等待出队。

Runnable将由空闲出列 并PoolThread执行。PoolThread.run()您可以在方法中看到这一点。执行完PoolThread 循环并尝试再次使任务出队,直到停止。

停止该ThreadPool方法ThreadPool.stop()被调用。调用的停止在isStopped成员内部记录。然后通过调用每个线程来停止池中的doStop()每个线程。请注意该 方法将如何在被调用后execute()抛出一个IllegalStateExceptionif 被调用。 execute()stop()

线程将在完成它们当前正在执行的任何任务后停止。注意 this.interrupt()调用PoolThread.doStop()。这可以确保在wait()调用内部的taskQueue.dequeue() 调用中阻塞的线程会中断wait()调用,并使dequeue()方法调用留下一个InterruptedExceptionthrows。这个异常在 PoolThread.run()方法中被捕获,报告,然后isStopped检查变量。由于isStopped现在是真的,PoolThread.run()将退出并且线程死亡。

以上就是关于“Java实现创建线程池”的介绍,大家如果想了解更多相关知识,不妨来关注一下动力节点的Java视频教程,里面的课程内容从入门到精通,细致全面,通俗易懂,适合小白学习,希望对大家能够有所帮助。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>