之前我说过,实现多线程的方式有4种,但是之前的文章中,我只介绍了两种,那么下面这两种,可以了解了解,不懂没关系。

之前的文章——>Java并发编程之多线程

使用ExecutorServiceCallableFuture实现有返回结果的线程

使用ExecutorServiceCallableFuture实现有返回结果的线程,也可以叫线程池方式。

ExecutorServiceCallableFuture三个接口都是属于**Executor框架。可返回值的任务必须实现Callable接口。通过ExecutorService执行Callable任务后,可以获取到一个Future的对象**,在该对象上调用get()就可以获取到Callable任务返回的结果了。

注意:Futureget方法是阻塞的,即线程无返回结果,get方法会一直等待。

其他创建线程的方式

除了以上四种主要的线程创建方式之外,也还有很多其他的方式可以启动多线程任务。比如通过Timer启动定时任务,或者通过像Spring Taskquartz这样的第三方任务调度框架也可以开启多线程任务,关于第三方任务调度框架的例子还请查询相关资料。

线程通信

什么是线程通信?

当多个线程共同操作共享的资源时,互相告知自己的状态以避免资源争夺。 线程通信主要可以分为三种方式,分别为 共享内存 、 消息传递 和 管道流 。

说白了就是用某些方法来获取线程的资源使用状态!

如何实现线程通信

wait方法:是Object类的方法,也就是说,所有的对象都有wait方法,调用了一个对象的wait方法,获得这个对象锁 的线程将等待,并释放对象锁。

调用对象的wait方法时,一定要有一个线程获得对象的对象锁,否则抛出异常。

notify方法:是Object类的方法,调用一个对象的notify方法,在这个对象上等待的线程中随机唤醒一个。

nofifyAll方法:在这个对象上等待的线程全都唤醒。

sleepwait的区别

  1. sleep是Thread类的方法,wait是Object类的方法。

  2. sleep不释放对象锁,wait释放对象锁。

  3. sleep只能到指定的时间自动唤醒,wait可以指定时间,也可以通过notify主动唤醒。

线程池

在项目中可能会创建大量的多线程,在执行完多线程后,线程对象被销毁,又有多线程需求时,再次创建多线程, 要反复的创建、销毁线程。可以用线程池管理多线程。

扩展

线程池模式一般分为两种:HS/HA半同步/半异步模式、L/F领导者与跟随者模式。

  • 半同步/半异步模式又称为生产者消费者模式,是比较常见的实现方式,比较简单。分为同步层、队列层、异步层三层。同步层的主线程处理工作任务并存入工作队列,工作线程从工作队列取出任务进行处理,如果工作队列为空,则取不到任务的工作线程进入挂起状态。由于线程间有数据通信,因此不适于大数据量交换的场合。
  • 领导者跟随者模式,在线程池中的线程可处在3种状态之一:领导者leader、追随者follower或工作者processor。任何时刻线程池只有一个领导者线程。事件到达时,领导者线程负责消息分离,并从处于追随者线程中选出一个来当继任领导者,然后将自身设置为工作者状态去处置该事件。处理完毕后工作者线程将自身的状态置为追随者。这一模式实现复杂,但避免了线程间交换任务数据,提高了CPU cache相似性。在ACE(Adaptive Communication Environment)中,提供了领导者跟随者模式实现。

线程池的伸缩性对性能有较大的影响。

  • 创建太多线程,将会浪费一定的资源,有些线程未被充分使用。
  • 销毁太多线程,将导致之后浪费时间再次创建它们。
  • 创建线程太慢,将会导致长时间的等待,性能变差。
  • 销毁线程太慢,导致其它线程资源饥饿。

Java并发编程扩展(线程通信、线程池)的更多相关文章

  1. [Java并发编程(二)] 线程池 FixedThreadPool、CachedThreadPool、ForkJoinPool?为后台任务选择合适的 Java executors

    [Java并发编程(二)] 线程池 FixedThreadPool.CachedThreadPool.ForkJoinPool?为后台任务选择合适的 Java executors ... 摘要 Jav ...

  2. Java 并发编程——Executor框架和线程池原理

    Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相当于生产者,执行任务 ...

  3. [Java并发编程(一)] 线程池 FixedThreadPool vs CachedThreadPool ...

    [Java并发编程(一)] 线程池 FixedThreadPool vs CachedThreadPool ... 摘要 介绍 Java 并发包里的几个主要 ExecutorService . 正文 ...

  4. Java 并发编程——Executor框架和线程池原理

    Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...

  5. Java并发编程:如何创建线程?

    Java并发编程:如何创建线程? 在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识, ...

  6. 【转】Java并发编程:如何创建线程?

    一.Java中关于应用程序和进程相关的概念 在Java中,一个应用程序对应着一个JVM实例(也有地方称为JVM进程),一般来说名字默认是java.exe或者javaw.exe(windows下可以通过 ...

  7. 2、Java并发编程:如何创建线程

    Java并发编程:如何创建线程? 在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识, ...

  8. 原创】Java并发编程系列2:线程概念与基础操作

    [原创]Java并发编程系列2:线程概念与基础操作 伟大的理想只有经过忘我的斗争和牺牲才能胜利实现. 本篇为[Dali王的技术博客]Java并发编程系列第二篇,讲讲有关线程的那些事儿.主要内容是如下这 ...

  9. Java并发编程(08):Executor线程池框架

    本文源码:GitHub·点这里 || GitEE·点这里 一.Executor框架简介 1.基础简介 Executor系统中,将线程任务提交和任务执行进行了解耦的设计,Executor有各种功能强大的 ...

随机推荐

  1. CF1479X Codeforces Round #700

    C Continuous City(图的构造) 题目大意:让你构造一个n\le 32的有向无环无重边图,使得从1走到n的所有路径长度在L,R之间,且每种长度的路径只有唯一一条,$L,R\le 1e6$ ...

  2. C++_STL_all_of

    all_of 功能描述 如果在[first,last)范围内的数组进行判断, 如果pred返回true返回true 否则返回false 等同于 template<class InputItera ...

  3. 序列化与反序列化、def的介绍与快速使用、cbv源码分析、APIView与request对象分析

    今日内容概要 序列化与反序列化 def介绍和快速使用 cbv源码流程分析 drf之APIView和Request对象分析 内容详细 1.序列化和反序列化 # api接口开发 最核心最常见的一个过程就是 ...

  4. 启动一个线程是调用 run()还是 start()方法?

    启动一个线程是调用 start()方法,使线程所代表的虚拟处理机处于可运行状态, 这意味着它可以由 JVM 调度并执行,这并不意味着线程就会立即运行.run()方 法是线程启动后要进行回调(callb ...

  5. java -的字符串hei

    字符串的不可变 String 对象是不可变的.查看 JDK 文档你就会发现,String 类中每一个看起来会修改 String 值的方法,实际上都是创建了一个全新的 String 对象,以包含修改后的 ...

  6. 机器学习之linear_model (线性回归算法模型)

    1.matplotlib 首先看一下这个静态图绘制模块 静态图形处理 数据分析三剑客 Numpy : 主要为了给pandas提供数据源 pandas : 更重要的数据结构 matplotlib : 静 ...

  7. 攻防世界 unserialize3

    unserialize3 class xctf{ public $flag = '111'; public function __wakeup(){ exit('bad requests'); } } ...

  8. IdentityServer4系列 | 支持数据持久化

    一.前言 在前面的篇章介绍中,一些基础配置如API资源.客户端资源等数据以及使用过程中发放的令牌等操作数据,我们都是通过将操作数据和配置数据存储在内存中进行实现的,而在实际开发生产中,我们需要考虑如何 ...

  9. 圣诞节,把网站所有的js代码都压缩成圣诞树吧。

    本文分两章节,分别讲解如何使用js2image这个库生成可以运行的圣诞树代码 和 js2image的原理. github地址:https://github.com/xinyu198736/js2ima ...

  10. 分享一个react 图片上传组件 支持OSS 七牛云

    react-uplod-img 是一个基于 React antd组件的图片上传组件 支持oss qiniu等服务端自定义获取签名,批量上传, 预览, 删除, 排序等功能 需要 react 版本大于 v ...