1、简述

线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能称为一个整体。

使线程之间进行通信后,在大大提高CPU利用率的同时还会使开发人员对各个线程任务在处理的过程中进行有效的把控。

2、如何实现线程间通信

2.1、等待(wait)/通知机制(notify)

方法 wait() 说明

方法wait()的作用是使当前执行的线程进行等待,wait() 方法是Object 类的方法,该方法用来将当前线程处于预执行状态,并且在调用wait()方法的代码处停止执行,直到接到通知或被终止。

在调用wait()之前,线程必须获得对象的锁,即只能在同步方法或代码块中调用wait()方法。在执行wait()方法后,当前线程释放锁。

如果 调用 wait() 时 没有持有适当的锁,则抛出IllegalMonitorStateException, 它是 RuntimeException 的 一个 子类。

方法 notify()说明

notify()方法在调用前,线程也必须获得该对象的锁,否则会抛出 IllegalMonitorStateException。该方法用来通知哪些等待该对象锁的其它线程,如果有多个线程等待,则有线程规划器随机挑选一个 wait 中的线程,对其发出notify 通知并使它准备回去该对象的锁。

在执行notify() 方法后,当前线程不会马上释放对象锁,要等待执行notify() 方法的线程执行完毕后,当前线程才会真正释放锁。

等待/通知机制总结:

wait()方法可以使调用该方法的线程释放共享资源的锁,然后从运行状态退出, 进入 等待队列,直到被再次唤醒。

notify() 方法可以随机唤醒一个等待队列中的线程,并使该线程退出等待队列, 进入 可运行状态,也就是 notify()方法仅通知“ 一个” 线程。

notifyAll()方法可以使所有正在等待队列中的全部线程 从等待状态退出, 进入可运行状态。 此时,优先级最高的那个线程最先执行,但也有可能随机执行, 因为 这要取决于JVM虚拟机的实现。

2.2、使用方法join

在很多情况下,主线程创建并启动子线程,如果子线程中要进行大量耗时运算,主线程往往早于子线程结束之前结束。这时如果主线程想等待子线程完成之后再结束,比如子线程处理一个数据,主线程要取得子线程的结果进行计算,就要用到join()方法了。

1、join()方法与 synchronized 的区别是:

join()方法内部使用 wait()方法进行等待,而synchrinized 关键字使用的是对象监视器原理实现同步。

2、join()方法与sleep()方法的区别:

join()方法内部是使用wait()方法来实现,所以join()方法具有释放锁的特点,而sleep()方法只是释放了CPU资源,但是不释放锁。

2.3、使用ThreadLocal

变量值得共享可以使用 publict static 变量的形式,所有的线程都使用同一个变量。如果每一个线程都有自己的共享变量该如何解决呢?JDK中提供了ThreadLocal 正式为了解决这样的问题。类 ThreadLocal 主要解决的是每个线程都可以拥有自己线程内的共享变量。

ThreadLocal 主要解决的是线程之间的隔离性,每个线程都有自己独有的值,互不干扰,同时该特性在父子关系的线程中也有效。

2.4、使用InheritableThreadLocal

使用类InheritableThreadLocal 可以在子线程中取得父线程继承下来的值。

但在使用类InheritableThreadLocal 时需要注意一点,如果子线程在取得值得同时,主线程将其中的值进行了修改,那么子线程取到的值还是旧值。

Java线程间如何通信(五)的更多相关文章

  1. java 线程间的通信 (wait / notify / notifyAll)

    package waitnotifytest; import java.util.Collections; import java.util.List; import com.google.commo ...

  2. Java线程间通信-回调的实现方式

    Java线程间通信-回调的实现方式   Java线程间通信是非常复杂的问题的.线程间通信问题本质上是如何将与线程相关的变量或者对象传递给别的线程,从而实现交互.   比如举一个简单例子,有一个多线程的 ...

  3. 说说Java线程间通信

    序言 正文 [一] Java线程间如何通信? 线程间通信的目标是使线程间能够互相发送信号,包括如下几种方式: 1.通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值:线程A在 ...

  4. 说说 Java 线程间通信

    序言 正文 一.Java线程间如何通信? 线程间通信的目标是使线程间能够互相发送信号,包括如下几种方式: 1.通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值:线程A在一个 ...

  5. Java多线程之线程的状态以及线程间协作通信导致的线程状态转换

      转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561589.html  一:线程的状态以及变化图 Java中线程中状态可分为五种:New(新建状态),Ru ...

  6. java多线程详解(6)-线程间的通信wait及notify方法

    Java多线程间的通信 本文提纲 一. 线程的几种状态 二. 线程间的相互作用 三.实例代码分析 一. 线程的几种状态 线程有四种状态,任何一个线程肯定处于这四种状态中的一种:(1). 产生(New) ...

  7. Java多线程中线程间的通信

    一.使用while方式来实现线程之间的通信 package com.ietree.multithread.sync; import java.util.ArrayList; import java.u ...

  8. Java 多线程(七) 线程间的通信——wait及notify方法

    线程间的相互作用 线程间的相互作用:线程之间需要一些协调通信,来共同完成一件任务. Object类中相关的方法有两个notify方法和三个wait方法: http://docs.oracle.com/ ...

  9. 【转】Java学习---线程间的通信

    [原文]https://www.toutiao.com/i6572378564534993415/ 两个线程间的通信 这是我们之前的线程. 执行效果:谁抢到资源,谁运行~ 实现线程交替执行: 这里主要 ...

随机推荐

  1. C# Redis分布式锁的应用 - 叶子栈 - SegmentFault 思否

    原文:C# Redis分布式锁的应用 - 叶子栈 - SegmentFault 思否 叶子 1 微信扫一扫 新浪微博 Twitter Facebook C# Redis分布式锁的应用 c#redis分 ...

  2. UEditor编辑器

    1.UEditor编辑器官网:http://ueditor.baidu.com/website/ 2.下载文件:选择  1.4.3.3 .Net版本 UTF-8板 3.建一个ueditor文件夹,将下 ...

  3. 原生 JS 绑定事件 移除事件

    监听事件的绑定与移除主要是addEventListener和removeEventListener的运用. addEventListener语法 element.addEventListener(ty ...

  4. [NOIP2018模拟赛10.16]手残报告

    [NOIP2018模拟赛10.16]手残报告 闲扯 炉石乱斗模式美滋滋啊,又颓到好晚... 上来T2先敲了树剖,看T1发现是个思博DP,然后没过大样例,写个暴力发现还是没过大样例!?才发现理解错题意了 ...

  5. 使用百度echarts仿雪球分时图(四)

    这章节来收拾一下一些小BUG,顺便把各个小提示信息也补上,分时图也就完成了. 上章节末尾提到的一个bug,就是第一个grid跟第三个grid之间是断开的,折线并没有连在一起,所以先来收拾这个问题.没有 ...

  6. 如何从零搭建hexo个人博客网站

    https://www.jianshu.com/p/adf65cbad393?utm_source=oschina-app   准备工作 github账号 node.js 环境搭建 git使用 mar ...

  7. linux 下安装python2.7.13

    1.下载所必要的依赖包 yum -y install python-devel openssl openssl-devel gcc sqlite sqlite-devel mysql-devel li ...

  8. shell变量引用

    var="www.sina.com.cn" echo ${var#*.} #sina.com.cn 从前向后删 echo ${var##*.} #.cn 贪婪模式从前向后删 ech ...

  9. windows BAT脚本2个服务器间传递文件

    1. 脚本功能: 实现2个服务器间文件的传递,例如从A服务器往B服务器上传文件 2. 实现步骤: 2.1 服务器连结,找到指定路径,读取所需要上传的文件,将文件名称复制到一个文件下 (此处考虑可能需要 ...

  10. Hdu 4661 树上拓扑序计数

    #include <bits/stdc++.h> using namespace std; typedef long long ll; ; ; ; ], nxt[MAXM << ...