我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java中线程池的示例分析

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java中线程池的示例分析

小编给大家分享一下Java中线程池的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

Java线程池

线程的缺点:

线程的创建它会开辟本地方法栈、JVM栈、程序计数器私有的内存,同时消耗的时候需要销毁以上三个区域,因此频繁的创建和销毁线程比较消耗系统的资源。

在任务量远远大于线程可以处理的任务量的时候,不能很好的拒绝任务。

所以就有了线程池:

使用池化的而技术来管理和使用线程。

线程池的优点

可以避免频繁的创建和销毁线程

可以更好的管理线程的个数和资源的个数。

线程池拥有更多的功能,比如线程池可以进行定时任务的执行。

线程池可以更友好的拒绝不能处理的任务。

线程池的6种创建方式

一共有7种创建方式

创建方式一:

创建固定个数的线程池:

package ThreadPoolDemo;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ThreadPoolDemo1 {    public static void main(String[] args) {        //创建一个固定个数的线程池        ExecutorService executorService = Executors.newFixedThreadPool(10);        //执行任务        for (int i = 0; i < 10; i++) {            executorService.execute(new Runnable() {                @Override                public void run() {                    System.out.println("线程名" + Thread.currentThread().getName());                }            });        }    }}

Java中线程池的示例分析

那么如果执行次数大于10次呢?

线程池不会创建新的线程,它会复用之前的线程。

Java中线程池的示例分析

Java中线程池的示例分析

那么如果只执行两个任务呢?它创建了是10个线程还是两个线程呢?

我们可以使用Jconsole来看一看:

Java中线程池的示例分析

Java中线程池的示例分析

结果是只有2个线程被创建。

创建方式二:

创建带有缓存的线程池:

适用于短期有大量的任务的时候使用

public class ThreadPoolDemo2 {    public static void main(String[] args) {        //创建带缓存的线程池        ExecutorService executorService = Executors.newCachedThreadPool();        for (int i = 0; i < 100; i++) {            executorService.execute(new Runnable() {                @Override                public void run() {                    System.out.println(Thread.currentThread().getName());                }            });        }    }}

Java中线程池的示例分析

方式三:

创建执行定时任务的线程池

package ThreadPoolDemo;import java.util.Date;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;public class ThreadPoolDemo3 {    public static void main(String[] args) {        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);        System.out.println("执行定时任务前的时间:" + new Date());        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {            @Override            public void run() {                System.out.println("执行任务的时间:" + new Date());            }        },1,2, TimeUnit.SECONDS);    }}

Java中线程池的示例分析

执行任务的四个参数的意义:

参数1:延迟执行的任务

参数2:延迟一段时间后执行

参数3:定时任务执行的频率

参数4:配合前两个参数使用,是2、3参数的时间单位

还有两种执行的方法:

只会执行一次的方法:

Java中线程池的示例分析

Java中线程池的示例分析

第三种的执行方式:

Java中线程池的示例分析

Java中线程池的示例分析

那么这种的执行方式和第一种的执行方式有什么区别呢?

当在两种执行的方式中分别加上sleep()之后:

Java中线程池的示例分析

方式一:

Java中线程池的示例分析

方式三:

Java中线程池的示例分析

结论很明显了:

第一种方式是以上一个任务的开始时间+定时的时间作为当前任务的开始时间

第三种方式是以上一个任务的结束时间来作为当前任务的开始时间。

创建方式四:

package ThreadPoolDemo;import java.util.Date;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;public class ThreadPoolDemo4 {    public static void main(String[] args) {        //创建单个执行任务的线程池        ScheduledExecutorService scheduledExecutorService                = Executors.newSingleThreadScheduledExecutor();        System.out.println("执行任务之前" + new Date());        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {            @Override            public void run() {                System.out.println("我是SingleThreadSchedule"+ new Date());            }        },3,1, TimeUnit.SECONDS);    }}

Java中线程池的示例分析

Java中线程池的示例分析

创建方式五:

创建单个线程的线程池

package ThreadPoolDemo;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ThreadPoolDemo5 {    public static void main(String[] args) {        //创建单个线程的线程池        ExecutorService executorService = Executors.newSingleThreadExecutor();        for (int i = 0; i < 20; i++) {            executorService.execute(new Runnable() {                @Override                public void run() {                    System.out.println("线程名 " +  Thread.currentThread().getName());                }            });        }    }}

Java中线程池的示例分析

创建单个线程池的作用是什么?

可以避免频繁创建和销毁线程所带来的性能的开销

它有任务队列,可以存储多余的任务

可以更好的管理任务

当有大量的任务不能处理的时候,可以友好的执行拒绝策略

创建方式六:

创建异步线程池根据当前CPU来创建对应个数的线程池

package ThreadPoolDemo;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ThreadPoolDemo6 {    public static void main(String[] args) {        ExecutorService executorService = Executors.newWorkStealingPool();        for (int i = 0; i < 10; i++) {             executorService.execute(new Runnable() {                @Override                public void run() {                    System.out.println("线程名" + Thread.currentThread().getName());                }            });        }    }}

Java中线程池的示例分析

运行结果为什么什么都没有呢?

看下面的异步与同步的区别就知道了。

加上这个

Java中线程池的示例分析

就可以输出结果了

Java中线程池的示例分析

线程池的第七种创建方式

前六种的创建方式有什么问题呢?

线程的数量不可控(比如带缓存的线程池)

工作任务量不可控(默认的任务队列的大小时Integer.MAX_VALUE),任务比较大肯会导致内存的溢出。

所以就可以使用下面的创建线程池的方式了:

package ThreadPoolDemo;import java.util.concurrent.LinkedBlockingDeque;import java.util.concurrent.ThreadFactory;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;public class ThreadPoolDemo7 {    private static int threadId = 0;    public static void main(String[] args) {        ThreadFactory threadFactory = new ThreadFactory() {            @Override            public Thread newThread(Runnable r) {                Thread thread = new Thread(r);                thread.setName("我是threadPool-" + ++threadId);                return thread;            }        };        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 3, 100,                TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(12),                threadFactory, new ThreadPoolExecutor.AbortPolicy());        for (int i = 0; i < 15; i++) {            threadPoolExecutor.execute(new Runnable() {                @Override                public void run() {                    System.out.println(Thread.currentThread().getName());                }            });        }    }}

Java中线程池的示例分析

参数说明:

Java中线程池的示例分析

  • 参数一:核心线程数|线程池正常情况下的线程 数量

  • 参数二:最大线程数|当有大量的任务的时候可以创建的最多的线程数

  • 参数三:最大线程的存活时间

  • 参数四:配合参数三一起使用的表示参数三的时间单位

  • 参数五:任务队列

  • 参数六:线程工厂

  • 参数七:决绝策略

注意事项:最大的线程数要大于等于核心的线程数

Java中线程池的示例分析

Java中线程池的示例分析

五种拒绝策略

Java中线程池的示例分析

Java中线程池的示例分析

为什么拒绝策略可以舍弃最新的任务或者最旧的任务呢?

因为LinkedBlockingDeque时FIFO的。

第五种:自定义的拒绝策略

Java中线程池的示例分析

Java中线程池的示例分析

ThreadPoolExecutor的执行方式

Java中线程池的示例分析

package ThreadPoolDemo;import java.util.concurrent.*;public class ThreadPoolDemo9 {    public static void main(String[] args) throws ExecutionException, InterruptedException {        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 4, 100,                TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(10), new ThreadPoolExecutor.DiscardOldestPolicy());        //线程池的执行方式一        threadPoolExecutor.execute(new Runnable() {            @Override            public void run() {                System.out.println("使用了execute()执行了线程池");            }        });        //线程池的执行方式二        Future<String> futureTask =                threadPoolExecutor.submit(new Callable<String>() {                    @Override                    public String call() throws Exception {                        return "使用submit(new Callable<>())执行了线程池";                    }                });        System.out.println(futureTask.get());            }}

无返回值的执行方式

Java中线程池的示例分析

有返回值的执行方式

Java中线程池的示例分析

ThreadPoolExecutor的执行流程

当任务量小于核心线程数的时候,ThreadPoolExecutor会创建线程来执行任务

当任务量大于核心的线程数的时候,并且没有空闲的线程时候,且当线程池的线程数小于最大线程数的时候,此时会将任务存

放到任务队列中

如果任务队列也被存满了,且最大线程数大于线程池的线程数的时候,会创建新的线程来执行任务。

如果线程池的线程数等于最大的线程数,并且任务队列也已经满了,就会执行拒绝策略。?

Java中线程池的示例分析

线程池的终止

shutdown()

线程池的任务会执行完

shutdownNow()

立即终止线程池,线程池的任务不会执行完

线程池的状态

Java中线程池的示例分析

异步、同步

1.Java 线程 同步与异步

多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线程的处理的数据,而B线程又修改了A线程处理的数理。显然这是由于全局资源造成的,有时为了解决此问题,优先考虑使用局部变量,退而求其次使用同步代码块,出于这样的安全考虑就必须牺牲系统处理性能,加在多线程并发时资源挣夺最激烈的地方,这就实现了线程的同步机制

同步

A线程要请求某个资源,但是此资源正在被B线程使用中,因为同步机制存在,A线程请求不到,怎么办,A线程只能等待下去

异步

A线程要请求某个资源,但是此资源正在被B线程使用中,因为没有同步机制存在,A线程仍然请求的到,A线程无需等待同步的方式:

发送请求

等待执行完成

有结果的返回

异步的方式

发请求

执行完成

另一个线程异步处理

处理完成之后返回回调结果

显然,同步最最安全,最保险的。而异步不安全,容易导致死锁,这样一个线程死掉就会导致整个进程崩溃,使用异步的机制,性能会有所提升

线程工厂

设想这样一种场景,我们需要一个线程池,并且对于线程池中的线程对象,赋予统一的线程优先级、统一的名称、甚至进行统一的业务处理或和业务方面的初始化工作,这时工厂方法就是最好用的方法了

package ThreadPoolDemo;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.ThreadFactory;public class ThreadFactoryDemo {    public static void main(String[] args) {        MyThreadFactory myThreadFactory = new MyThreadFactory();        ExecutorService executorService =  Executors.newFixedThreadPool(10,myThreadFactory);        for (int i = 0; i < 10; i++) {            executorService.execute(new Runnable() {                @Override                public void run() {                    System.out.println("使用线程工厂设置的线程名:"+ Thread.currentThread().getName() +                            " 使用线程工厂设置的线程的优先级" + Thread.currentThread().getPriority());                }            });        }    }    private static int count = 0;     static class MyThreadFactory implements ThreadFactory{         @Override         public Thread newThread(Runnable r) {             Thread thread = new Thread(r);             thread.setPriority(8);             thread.setName("thread--" + count++);             return thread;         }     }}

Java中线程池的示例分析

以上是“Java中线程池的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java中线程池的示例分析

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java中线程池的示例分析

小编给大家分享一下Java中线程池的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Java线程池线程的缺点:1.线程的创建它会开辟本地方法栈、JVM栈、程
2023-06-20

Java线程池的示例分析

小编给大家分享一下Java线程池的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!为什么需要线程池我们知道创建线程的常用方式就是 new Thread()
2023-06-22

Java并发编程之线程池的示例分析

这篇文章将为大家详细讲解有关Java并发编程之线程池的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。什么是线程池是一种基于池化思想管理线程的工具。池化技术:池化技术简单点来说,就是提前保存大量的资
2023-06-20

Java中线程的示例分析

这篇文章主要介绍了Java中线程的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。什么是进程?电脑中时会有很多单独运行的程序,每个程序有一个独立的进程,而进程之间是相互
2023-06-25

Java多线程之线程池七个参数的示例分析

这篇文章主要介绍Java多线程之线程池七个参数的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!ThreadPoolExecutor是JDK中的线程池实现,这个类实现了一个线程池需要的各个方法,它提供了任务提交
2023-06-14

spring task和线程池的示例分析

小编给大家分享一下spring task和线程池的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!spring task和线程池的研究1、如何实现sprin
2023-06-22

Linux系统线程池的示例分析

Linux系统线程池的示例分析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。实现原理程序启动之前,创建一定数量的线程,放入空闲的队列中,初始化线程池。这些线程均处于阻塞状态
2023-06-28

Python中线程池模块之多线程的示例分析

这篇文章将为大家详细讲解有关Python中线程池模块之多线程的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1、线程池模块引入from concurrent.futures import Thre
2023-06-15

java线程池中类的继承实例分析

这篇文章主要介绍java线程池中类的继承实例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!常用的java框架有哪些1.SpringMVC,Spring Web MVC是一种基于Java的实现了Web MVC设计模
2023-06-14

java中多线程的示例分析

这篇文章主要介绍了java中多线程的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。java多线程并发与并行:并行: 指两个或多个事件在同一时刻发生 ( 同时发生 )
2023-06-20

Java程序中多线程的示例分析

这篇文章主要介绍了Java程序中多线程的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。  为什么会排队等待?  下面的这个简单的 Java 程序完成四项不相关的任务。
2023-06-03

java中进程和线程的示例分析

小编给大家分享一下java中进程和线程的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!为什么会有进程在简单的批处理操作系统中,作业时串行执行的,即一个作业
2023-06-20

Java多线程的示例分析

这篇文章给大家分享的是有关Java多线程的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。线程的创建1.继承Thread2.实现Runnable3.实现Callable使用继承Thread类来开发多线程的应
2023-06-20

java线程编程的示例分析

这篇文章给大家分享的是有关java线程编程的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。线程基础◆线程(thread)其实是控制线程(thread of control)的缩写.每一个线程都是独立的,因
2023-06-03

Java多线程之Interrupt中断线程的示例分析

小编给大家分享一下Java多线程之Interrupt中断线程的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、测试代码https://gitee.com/zture/spring-test/blob/master
2023-06-15

java中stringbuffer线程安全分析的示例

这篇文章主要介绍java中stringbuffer线程安全分析的示例,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!常用的java框架有哪些1.SpringMVC,Spring Web MVC是一种基于Java的实现了
2023-06-14

Java并发线程池实例分析讲解

这篇文章主要介绍了Java并发线程池实例,线程池——控制线程创建、释放,并通过某种策略尝试复用线程去执行任务的一个管理框架,从而实现线程资源与任务之间一种平衡
2023-02-02

Java线程运行的示例分析

这篇文章将为大家详细讲解有关Java线程运行的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。栈与栈帧JVM中由堆、栈、方法区所组成,其中栈内存就是分配给线程使用的,每个线程启动后,虚拟机都会为其分
2023-06-29

客户端JavaScript线程池设计的示例分析

这篇“客户端JavaScript线程池设计的示例分析”除了程序员外大部分人都不太理解,今天小编为了让大家更加理解“客户端JavaScript线程池设计的示例分析”,给大家总结了以下内容,具有一定借鉴价值,内容详细步骤清晰,细节处理妥当,希望
2023-06-28

Java多线程程序的示例分析

今天就跟大家聊聊有关Java多线程程序的示例分析,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。我们在使用Java多线程程序的时候会遇到不少的问题,当我们解决这个问题的时候在源代码中就
2023-06-17

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录