3 - 线程池 Java内置的线程池

news2024/12/23 10:26:18

1、ExecutorService的介绍

ExecutorService 接口继承了Executor 接口,是Executor 的子接口。

Executors类 提供工厂方法用来创建不同类型的线程池。Executors是工具类,他提供对ThreadPoolExecutor的封装,会产生几种线程池供大家使用。

关于 Executor 、ExecutorService、Executors三者的区别

参考:Executor, ExecutorService 和 Executors 间的区别与联系 - 夏威夷8080 - 博客园

UML简要类图关系:

2、ExecutorService 的获取 - submit()方法

注:返回值都是 ExecutorService

3种方法以及每种方法对应的一个重载的方法

如重载方法:newCachedThreadPool(ThreadFactory threadFactory):

ThreadFactory 也是一个接口,该接口允许我们自己去写实现类,在实现类的内部只需要创建一个线程对象即可——这样的话,相当于我们自己(程序员)可以控制线程池中每一个线程对象的创建。

 上面的 “无界队列方式” —— 是指任务累加或者说缓存的时候,是不限制数量的。

(1)newCachedThreadPool() 方法、

以及其重载的方法法 newCachedThreadPool(ThreadFactory threadFactory)

:创建一个默认的线程池对象,里面的线程可重用,且在第一次使用时才创建;

重载的:线程池中的所有线程都使用ThreadFactory来创建,这样的线程无需手动启动,自动执行。

代码示例:MyTest01

package com.zhoulz.demo02;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

/**
 * 练习 Executors 获取ExecutorService,然后调用方法,提交任务;
 * newCachedThreadPool()方法、
 *         以及其重载的方法newCachedThreadPool(ThreadFactory threadFactory)
 */
public class MyTest01 {
    public static void main(String[] args) {
        //test1(); // 下面test1()中的内容被提取出来了—— 快捷键Shift+Alt+M:提取方法Extract Method
                   // 提取的原因是因为方便测试。接下来要测试newCachedThreadPool()重载的方法

        test2();
    }

    //(1)练习newCachedThreadPool()方法
    private static void test1() {
        // 1、使用工厂类——获取线程池对象
        final ExecutorService es = Executors.newCachedThreadPool();
        // 然后就可以调用方法 :如提交任务、shutdown()方法关闭提交
        // 2、提交任务 —— 任务可以是Runnable类型的对象,也可以是Callable类型的对象
        // 为了代码的整洁性,下面单独写了一个任务类。(也可以写一个匿名内部类)
        // 可以通过循环的方式来提交任务
        for (int i = 1; i <= 10; i++) {
            es.submit(new MyRunnable(i));
        }
    }

    //(2)练习newCachedThreadPool()重载的方法—— (在里面直接传参数 ThreadFactory threadFactory)
    private static void test2() {
        // 1、使用工厂类——获取线程池对象
        final ExecutorService es = Executors.newCachedThreadPool(new ThreadFactory() {
            int n = 1;
             // 匿名内部类的内部,允许我们直接创建一个线程对象。所以下面return的时候,可以直接new
            @Override
            public Thread newThread(Runnable r) {
                //return null;
                // 直接 new,并把Runnable的对象作为一个实参
                return new Thread(r,"自定义的线程名称" + n++);
                // 这样,创建出来的线程 new Thread()就可以和这个任务Runnable r 绑定在一起了!!!
                // 然后就可以执行了。。。
                // 还可以指定线程名称、加编号 n ...见上
            }
        });

        // 2、提交任务(这里是通过匿名内部类的方式,见上面)
        for (int i = 1; i <= 10; i++) {
            es.submit(new MyRunnable(i));
        }
    }
}

/**
 * 任务类:包含一个任务编号,在任务中,打印出是哪一个线程正在执行任务
 */
class MyRunnable implements Runnable{
    // 为了对任务做一个区分,可以加一个编号,不能通过run()方法传进来,所以要通过构造方法
    private int id;

    public MyRunnable(int id) {
        this.id = id;
    }

    @Override
    public void run() {
        // 获取线程的名称,打印一句话(这就是要执行的任务)
        String name = Thread.currentThread().getName();
        System.out.println(name + "执行了任务。。。" + id);
    }
}

结果:

test01:创建了10个线程

test02:—— 可见10个线程都是自定义创建的。

  

(2)newFixedThreadPool(int nThreads) 方法、以及其重载的方法 newFixedThreadPool(int nThreads, ThreadFactory threadFactory)

: 创建一个可重用固定线程数的线程池 ;

 重载的:创建一个可重用固定线程数的线程池且线程池中的所有线程都使用ThreadFactory来创建。

代码示例:MyTest02(基本同MyTest01)

package com.zhoulz.demo02;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

/**
 * 练习 Executors 获取ExecutorService,然后调用方法,提交任务;
 *(2)newFixedThreadPool(int nThreads)方法、以及其重载的方法
 *         newFixedThreadPool(int nThreads, ThreadFactory threadFactory)
 */
public class MyTest02 {
    public static void main(String[] args) {
        //test1();
        test2();
    }

    //(1)练习newFixedThreadPool(int nThreads)方法
    private static void test1() {
        // 1、使用工厂类——获取线程池对象
        final ExecutorService es = Executors.newFixedThreadPool(3);
        // 2、提交任务
        for (int i = 1; i <= 10; i++) {
            es.submit(new MyRunnable2(i));
        }
    }

    //(2)练习newCachedThreadPool()重载的方法
    private static void test2() {
        // 1、使用工厂类——获取线程池对象
        final ExecutorService es = Executors.newFixedThreadPool(3,new ThreadFactory() {
            int n = 1;
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r,"自定义的线程名称" + n++ +"-zlz");
            }
        });

        // 2、提交任务
        for (int i = 1; i <= 10; i++) {
            es.submit(new MyRunnable2(i));
        }
    }
}

/**
 * 任务类:包含一个任务编号,在任务中,打印出是哪一个线程正在执行任务
 */
class MyRunnable2 implements Runnable{
    private int id;

    public MyRunnable2(int id) {
        this.id = id;
    }

    @Override
    public void run() {
        // 获取线程的名称,打印一句话
        String name = Thread.currentThread().getName();
        System.out.println(name + "执行了任务。。。" + id);
    }
}

结果:

test01:只创建了3个线程 

test02自定义的创建了3个线程 

这是匿名内部类中自定义的线程对象(任务?)加了“-zlz”作区分

结合如下输出结果,可见 执行的任务/线程是匿名内部类里的,而不是MyRunnable2里的。

 但是为什么没执行呢?(下面还是提交了任务 new MyRunnable2(i) 的啊)

(3)newSingleThreadExecutor()方法、

以及其重载的方法 newSingleThreadExecutor(ThreadFactory threadFactory)

:创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程;

重载的:创建一个使用单个 worker 线程的 Executor,且线程池中的所有线程都使用ThreadFactory来创建。

代码示例:MyTest03(基本同MyTest01、MyTest02)

package com.zhoulz.demo02;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

/**
 * 练习 Executors 获取ExecutorService,然后调用方法,提交任务;
 *(3)newSingleThreadExecutor()方法、以及其重载的方法
 *        newSingleThreadExecutor(ThreadFactory threadFactory)
 */
public class MyTest03 {
    public static void main(String[] args) {
        //test1();
        test2();
    }

    //(1)练习newFixedThreadPool(int nThreads)方法
    private static void test1() {
        // 1、使用工厂类——获取线程池对象
        final ExecutorService es = Executors.newSingleThreadExecutor();
        // 2、提交任务
        for (int i = 1; i <= 10; i++) {
            es.submit(new MyRunnable3(i));
        }
    }

    //(2)练习newCachedThreadPool()重载的方法
    private static void test2() {
        // 1、使用工厂类——获取线程池对象
        final ExecutorService es = Executors.newSingleThreadExecutor(new ThreadFactory() {
            int n = 1;
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r,"自定义的线程名称" + n++ +"-zlz");
            }
        });

        // 2、提交任务
        for (int i = 1; i <= 10; i++) {
            es.submit(new MyRunnable3(i));
        }
    }
}

/**
 * 任务类:包含一个任务编号,在任务中,打印出是哪一个线程正在执行任务
 */
class MyRunnable3 implements Runnable{
    private int id;

    public MyRunnable3(int id) {
        this.id = id;
    }

    @Override
    public void run() {
        // 获取线程的名称,打印一句话
        String name = Thread.currentThread().getName();
        System.out.println(name + "执行了任务。。。" + id);
    }
}

结果:

test01:只创建了1个线程

test02:自定义的只创建了1个线程

 3、shutdown()方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/74141.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

20 个超级实用的 CSS 技巧,帮助你成为更好的开发者

在开发项目中&#xff0c;修改输入占位符样式&#xff0c;多行文本溢出&#xff0c;隐藏滚动条&#xff0c;修改光标颜色&#xff0c;水平和垂直居中等等&#xff0c;这些都是我们非常熟悉的开发场景&#xff01;前端开发者几乎每天都会和它们打交道&#xff0c;因此&#xff0…

Visual Studio 平台下基于 C# /.NET 的 Android 开发

文章目录Part.I IntroductionChap.I 环境搭建Part.II ExamplePart.I Introduction 因为想尝试一下移动端的开发&#xff0c;所以在网上简单搜了一下移动端开发可以使用的语言&#xff0c;发现 Java, C# 等都可以。虽然用Java的居多&#xff0c;但是笔者对C#较为熟悉一些&#x…

TikTok变现冲不冲?这些TikTok选品方法赶快用上

TikTok电商商家们通常最忧愁的就是不知道如何有效进行TikTok选品。有时候因为选到难卖的产品&#xff0c;就会导致库存积压、资金紧缺等问题。今天&#xff0c;为TikTok电商商家们分享一些好用、有效的TikTok选品方法~ TikTok选品方法一——利用电商平台数据选品 除了一些偏地…

[附源码]JAVA毕业设计文物管理系统(系统+LW)

[附源码]JAVA毕业设计文物管理系统&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&…

速卖通官方公告:“不活跃商品”管理规则,将于12月12日生效!

最新平台动向&#xff1a;速卖通“黑色星期五”大促开始。作为海外最火的促销购物节黑五与世界杯重叠&#xff0c;速卖通上热销海外的国货有了显著的新趋势&#xff1a;越来越多具有更高科技含量的国货在海外走红。其中&#xff0c;速卖通上国产VR眼镜成为今年最火的商品&#…

Kubernetes 调度器详解

kube-scheduler是 kubernetes 系统的核心组件之一&#xff0c;主要负责整个集群资源的调度功能&#xff0c;根据特定的调度算法和策略&#xff0c;将 Pod 调度到最优的工作节点上面去&#xff0c;从而更加合理、更加充分的利用集群的资源&#xff0c;这也是我们选择使用 kubern…

构建高性能内存队列:Disruptor yyds~

Java中有哪些队列 ArrayBlockingQueue 使用ReentrantLockLinkedBlockingQueue 使用ReentrantLockConcurrentLinkedQueue 使用CAS等等 我们清楚使用锁的性能比较低&#xff0c;尽量使用无锁设计。接下来就我们来认识下Disruptor。 Disruptor简单使用 github地址&#xff1a;P…

R语言建立和可视化混合效应模型mixed effect model

全文下载链接&#xff1a;http://tecdat.cn/?p20631我们已经学习了如何处理混合效应模型。本文的重点是如何建立和_可视化_ 混合效应模型的结果&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。相关视频设置本文使用数据集&#xff0c;用于探索草食动物种群对…

Linux Capabilities

Linux Capabilities 入门教程&#xff1a;基础实战篇 为了对 root 权限进行更细粒度的控制&#xff0c;实现按需授权&#xff0c;Linux 引入了另一种机制叫capabilities。Capabilites 作为线程&#xff08;Linux 并不真正区分进程和线程&#xff09;的属性存在&#xff0c;每个…

极客时间Kafka - 06 Kafka 消费者组 Consumer Group 到底是什么?

文章目录1. 消费者组到底是什么&#xff1f;2. Consumer Group下的Consumer实例个数3. 消费者位移Offset4. 重平衡1. 消费者组到底是什么&#xff1f; 消费者组&#xff0c;即 Consumer Group&#xff0c;应该算是 Kafka 比较有亮点的设计了。那么何谓 Consumer Group 呢&…

JAVA SCRIPT设计模式--行为型--设计模式之State状态者模式(20)

JAVA SCRIPT设计模式是本人根据GOF的设计模式写的博客记录。使用JAVA SCRIPT语言来实现主体功能&#xff0c;所以不可能像C&#xff0c;JAVA等面向对象语言一样严谨&#xff0c;大部分程序都附上了JAVA SCRIPT代码&#xff0c;代码只是实现了设计模式的主体功能&#xff0c;不代…

ToDesk企业版使用测试:破解企业远程办公难题,更安全更高效

❤️作者主页&#xff1a;小虚竹 ❤️作者简介&#xff1a;大家好,我是小虚竹。Java领域优质创作者&#x1f3c6;&#xff0c;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;掘金年度人气作者&#x1f3c6;&#xff0c;阿里云专家博主&#x1f3…

Phoenix安装部署

目录官网地址Phoenix 部署连接二次连接&#xff0c;连接失败解决官网地址 link Phoenix 部署 上传并解压 tar 包 更名 复制 server 包并拷贝到各个节点的 hbase/lib 配置环境变量 sudo vim /etc/profile.d/my_env.sh#phoenix export PHOENIX_HOME/opt/module/phoenix e…

抗病毒面料之外,安奈儿价值内核彰显

伴随着防控措施的不断优化&#xff0c;消费板块重回资本视野&#xff0c;其中童装巨头安奈儿因将推出“抗病毒抗菌面料”备受关注&#xff0c;14天收获10个涨停板。 目前安奈儿凭借抗病毒面料吸引了无数资本的目光&#xff0c;但这也是一把双刃剑。虽然抗病毒面料为安奈儿带来了…

数字化棋牌室 | 会员管理预约系统 | 棋牌室小程序

棋牌室在城市与农村都是部分老年人与年轻人的经常去的娱乐场所&#xff0c;以前这些场所里总是挤满了人&#xff0c;但现在越来越多的棋牌室即使环境装修的漂亮、设备高端完善等依然面对流量难题及管理难题&#xff0c;同时由于棋牌室具有社区属性&#xff0c;因此也有不少商家…

ARM微控制器MK24FN1M0VDC12、MKV10Z128VLH7低功耗MCU资料

MK24FN1M0VDC12 IC MCU 32BIT 1MB FLASH 121XFBGA 说明&#xff1a;Kinetis K2x 32位微控制器是低功耗mcu&#xff0c;通过智能片上集成大大节省了BOM。这些mcu基于ArmCortex-M4核心&#xff0c;提供完整和可选的高速USB 2.0 on - on - go (OTG)&#xff0c;包括无晶体设备功能…

干货 | 数字经济创新创业——数据是数字经济的基础

下文整理自清华大学大数据能力提升项目能力提升模块课程“Innovation & Entrepreneurship for Digital Economy”&#xff08;数字经济创新创业课程)的精彩内容。主讲嘉宾&#xff1a;Kris Singh: CEO at SRII, Palo Alto, CaliforniaVisiting Professor of Tsinghua Unive…

RTSP 协议漫谈,揭秘 RTSP 协议内幕

RTSP&#xff08;Real Time Streaming Protocol&#xff09;实时流传输协议&#xff0c;定义在 RFC2326&#xff0c;是 TCP/IP 协议体系中的一个应用层协议&#xff0c;由哥伦比亚大学、网景和 RealNetworks 公司提交的 IETF RFC 标准。该协议定义了一对多应用程序如何有效地通…

Linux用户管理详解

Linux用户管理详解 前言 Linux用户即Linux的使用者&#xff0c;是指使用Linux系统或服务的人员&#xff0c;通常用户对应拥有一个用户账号&#xff0c;并对用户名识别。正常登录Linux系统&#xff0c;本质是登录系统&#xff0c;但是Linux支持同一时间多个用户同时登陆&#x…

JSP ssh服装定制电子商务系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 JSP ssh服装定制电子商务系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采 用B/S模式开发。开发环境为TOMCA…