Java高级编程——多线程(JDK5新增创建线程方式Callable,线程池)

2023-10-27

一、实现Callable接口

1.1与Runnable相比

与Runnable相比Callable功能更加强大

  • 相比于run()方法,call()可以有返回值
  • 方法可以抛出异常,被外面的操作捕获
  • 支持范型的返回值
  • 需要借助FutureTask类,比如获取返回结果

1.2实现步骤

①创建Callable接口实现类

Callable是一个范型接口

class Thread1 implements Callable {

}

②重写call方法

    @Override
    public Object call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= 100 ; i++) {
            if (i % 2 == 0 ) {
                System.out.println(i);
                sum += i;
            }
        }
        return sum;
    }

③新建实现类对象

Thread1 thread1 = new Thread1();

④将实现类对象作为参数传递待FutureTask的构造器中,创建FutureTask的对象

FutureTask实现了Runnable接口,所以FutureTask的对象也是Runnable对象(实现了Runnable接口),可以交给Thread

FutureTask futureTask = new FutureTask(thread1);

⑤将FutureTask的对象传到Thread的构造器中,创建Thread类的对象并start()

        //FutureTask也实现了Runnable接口
        Thread t1 = new Thread(futureTask);

        t1.start();

⑥获取Callable返回值 futureTask.get()

        try {
            //futureTask.get()获取的是FutureTask构造器参数Callable实现类重写的call()的返回值
            System.out.println(futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

二、使用线程池

2.1.1 背景

经常创建和销毁、使用量特别大的资源,比如并发情况下的线程,对性能影响很大

2.1.2 思路

提前创好多个线程,放在线程池中,使用时直接获取,使用完放回池中。可以避免频繁创建销毁、实现重复利用。

2.1.3 好处

①提高响应速度:减少了创建新线程的时间
②降低资源消耗:重复利用线程池中线程,不需要每次都创建
③便于线程管理

2.2 创建线程池

方式一、线程池工具类Executors调用方法

        //Executors工具类、线程池的工厂类,用法语创建并返回不同类型的线程池
        //1、创建一个可根据需要创建性线程的线程池
        Executors.newCachedThreadPool();

        //2、创建一个可重用固定线程数的线程池
        Executors.newFixedThreadPool(n);


        //3、创建一个只有一个线程的线程池
        Executors.newSingleThreadExecutor();

        //4、创建一个线程池,它可安排再给定延迟后运行命令或者定期地执行
        应用:定时器
        Executors.newScheduledThreadPool(n);

Executors的底层也是基于线程池的实现类ThreadPoolExecutor创建线程池对象

2.2.1 Executors.newFixedThreadPool(int n);

①创建指定线程数量的线程池

ExecutorService service = Executors.newFixedThreadPool(10);

②新建Runnable或Callable接口实现类,并重写run方法或call方法(新建任务)
Runnable:

class PoolThread implements Runnable{
    @Override
    public void run() {
        for (int i = 1; i <= 100 ; i++) {
            if (i % 2 == 0 ) {
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
}

Callable

class PoolThread1 implements Callable {

    @Override
    public Object call() {
        for (int i = 1; i <= 100 ; i++) {
            if (i % 2 == 0 ) {
                continue;
            }
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
        return null;
    }
}

③ 执行指定的线程操作需要提供实现类对象
excute适用于Runnable对象,submit适用于Callable对象 excute在Excutor中
Runnable

service.execute(new PoolThread());//适合适用于Runnable,参数只能是Runnable

Callable

service.submit(new FutureTask(new PoolThread1()));//返回一个FutureTask

④关闭连接池

service.shutdown();//等待全部任务执行完毕后关闭线程池
service.shutdownNow();//立即关闭线程池,可能造成任务丢失

运行结果

...
pool-1-thread-1:72
pool-1-thread-1:74
pool-1-thread-1:76
pool-1-thread-1:78
pool-1-thread-1:80
pool-1-thread-2:45
pool-1-thread-2:47
pool-1-thread-1:82
pool-1-thread-1:84
pool-1-thread-1:86
...

方式二、JDK5提供代表线程池的接口:ExcutorService

//构造器构造
public ThreadPoolExecutor(int corePoolSize,                      参数说明:  线程池数量(核心线程)>0
							int maximumPoolSize,                            线程池可支持的最大数量 >=核心线程
							long keepAliveTime,                             指定临时线程的最大存活时间 >=0
							TimeUnite unit,                                 指定存活时间的单位,秒,分,时,天  时间单位
							BlockingQueue<Runnable> workQueue,              指定任务队列    不为 null
							ThreadFactory threadFactory,					指定用来创建线程的线程工厂   不为 null
							RejectExecutionHandler handler)                 指定线程忙,任务满时,新任务来了的梳理方式   不为 null

2.3 管理线程池

2.3.1 设置线程池属性

//类型强转
        ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;
        service1.setCorePoolSize(15);
        service1.setKeepAliveTime();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java高级编程——多线程(JDK5新增创建线程方式Callable,线程池) 的相关文章

随机推荐

  • 全网最全面的西门子1500硬件冗余项目,博图15.1

    全网最全面的西门子1500硬件冗余项目 博图15 1 非常全面 CAD图纸 合同 上位机软件是intcohid 644593395557
  • 序列检测器

    序列检测器 目标检测连续的三个1 6 6 4章节 第一种方法是采用状态机 第二种方法是用移位寄存器来存储输入值 并检测寄存器的值是否和预设的序列相匹配
  • Linux系统gdb调试常用命令

    GDB GNU调试器 是一款常用的调试工具 用于调试C C 等编程语言的程序 以下是一些常用的GDB命令 1 启动程序 gdb
  • jQuery笔记 (完整详细版)

    2018 9 17 星期一 jQuery 第一章 初识jQuery 第二章 jQuery的事件和API 第三章 jQuery中的动画 第一章 初识jQuery 一 jQuery简介 1 什么是jQuery jQuery是一个优秀的JavaS
  • VUE高德地图实现根据移动覆盖点获得经纬度坐标和详细地址及根据经纬度确定覆盖点

    经纬度手动定位 输入经纬度 显示详细地址 async handleMapPositioning const result await this api getProductLocation this unionId this reMap n
  • C++类

    一个简单的类 定义一个类 class MyClass 类名 public 访问修饰符 MyClass 构造函数 MyClass 析构函数 void function 成员函数 也叫成员方法 private int m data 成员数据 不
  • C++ 计算代码运行时间

    在算法比较中 耗时是一个重要的指标 每次都要去搜别人的博客 今天摘抄一下askunix hjh的博客 感谢博主 原文记录了三种办法 我选择了其中比较易懂的 GetTickCount是函数 GetTickCount返回 retrieve 从操
  • k8s部署Dashboard可视化插件

    DashBoard可视化插件 可以给用户提供一个可视化的Web界面来查看当前集群的各种信息 一 下载Dashboard所需的yaml文件 wget https raw githubusercontent com kubernetes das
  • 关闭虚拟机的防火墙

    CentOS6 切换至root用户 然后输入 service iptables stop 命令即可关闭防火墙 CentOS7 切换至root用户 先输入 systemctl stop firewalld 命令关闭防火墙 然后输入 syste
  • dataclass的作用

    dataclasss的作用 from dataclasses import dataclass dataclass class Person name str age int gender str unknown init 方法用于初始化对
  • HTML转义字符大全

    1 常用转义字符 转义字符串 Escape Sequence 也称字符实体 Character Entity 在HTML中 定义转义字符串的原因有两个 第一个原因是像 lt 和 gt 这类符号已经用来表示HTML标签 因此就不能直接当作文本
  • 学习 bison 原理(四)

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 学习 bison 原理 四 第5步 转变第 4 步的状态机为确定的 LALR 状态机 在 三 中我们已经看到 LR0 状态机很可能有 r r 冲突 s r 冲突 那这关键的
  • QList与QVector

    看qt的文档 只要是不要求数据所存放的内存是连续的 都建议用QList 因为QList的查询速度跟QVecotr是差不多的 感觉有点奇怪 至少与我之前所认识的List的查询是一不样的 好吧 看看源码的 原来QList的元素的指针是通过数组来
  • 文本处理——基于 word2vec 和 CNN 的文本分类 :综述 & 实践(一)

    原文地址 https zhuanlan zhihu com p 29076736 导语 传统的向量空间模型 VSM 假设特征项之间相互独立 这与实际情况是不相符的 为了解决这个问题 可以采用文本的分布式表示方式 例如 word embedd
  • ohmyzsh主题修改

    1 选择主题 ohmyzsh Themes by Github 2 修改zsh配置 vim zshrc 3 使配置生效 source zshrc 效果如下
  • 二、初识arduino uno开发板

    开发板参数表 什么是arduino Arduino是一款便捷灵活 方便上手的开源电子原型平台 包含硬件 各种型号的Arduino板 和软件 ArduinoIDE 构建于开放原始码simple I O介面版 并且具有使用类似Java C语言的
  • Golang闭包陷阱

    golang闭包陷阱本质原理其实是range陷阱 Golang for range陷阱 ep 1 func main var values int 1 2 3 4 5 for value range values go func fmt P
  • 编译 OneFlow 模型

    本篇文章译自英文文档 Compile OneFlow Models tvm 0 14 dev0 documentation 作者是 BBuf Xiaoyu Zhang GitHub 更多 TVM 中文文档可访问 Apache TVM 是一个
  • 3月6日服务器例行维护公告,2014年3月6日停机维护公告

    亲爱的玩家 为了保证服务器的稳定和服务质量 新大话西游2 将于2014年3月6日早上8 00停机 进行每周例行的维护工作 维护时间为早上08 00至09 30 同时 本次停机还将发布最新的客户端补丁 patch2 0 476 如果在维护期间
  • Java高级编程——多线程(JDK5新增创建线程方式Callable,线程池)

    创建线程的第三 四种方式 一 实现Callable接口 1 1与Runnable相比 1 2实现步骤 创建Callable接口实现类 重写call方法 新建实现类对象 将实现类对象作为参数传递待FutureTask的构造器中 创建Futur