博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java多线程——线程通信
阅读量:6731 次
发布时间:2019-06-25

本文共 894 字,大约阅读时间需要 2 分钟。

一、线程通信目标

1、线程通信的目标是使线程间能够互相发送信号

2、线程通信使线程能够等待其他线程的信号

 

二、几种方式

1、通过共享对象

 

2、忙等待

 线程 B 运行在一个循环里,以等待信号 (不释放cpu)

 

3、wait,notify和notifyAll

wait会使线程进入睡眠或者非运行状态,释放cpu使用权;

线程必须在同步块里调用 wait()或者 notify();

当一个线程调用一个对象的 notify()方法,正在等待该对象的所有线程中将有一个线程被唤醒并允许执行(校注:这个将被唤醒的线程是随机的,不可以指定唤醒哪个线程)。同时也提供了一个 notifyAll()方法来唤醒正在等待一个给定对象的所有线程;

 

三、信号丢失

notify()和 notifyAll()方法不会保存调用它们的方法,因为当这两个方法被调用时,有可能没有线程处于等待状态。通知信号过后便丢弃了。因此,如果一个线程先于被通知线程调用 wait()前调用了 notify(),等待的线程将错过这个信号。

 

为了避免丢失信号,必须把它们保存在信号类里。

 

四、假唤醒

线程有可能在没有调用过 notify()和 notifyAll()的情况下醒来。这就是所谓的假唤醒(spurious wakeups)。

 

为了防止假唤醒,保存信号的成员变量将在一个 while 循环里接受检查,而不是在 if 表达式里。这样的一个 while 循环叫做自旋锁(校注:这种做法要慎重,目前的 JVM 实现自旋会消耗 CPU,如果长时间不调用 doNotify 方法,doWait 方法会一直自旋,CPU 会消耗太大)。被唤醒的线程会自旋直到自旋锁(while 循环)里的条件变为 false。

 

五、不要在字符串常量或全局对象中调用 wait()

在空字符串作为锁的同步块(或者其他常量字符串)里调用 wait()和 notify()产生的问题是,JVM/编译器内部会把常量字符串转换成同一个对象;

 

应该使用对应唯一的对象

转载于:https://www.cnblogs.com/lwcoding/p/6672829.html

你可能感兴趣的文章
修改VS自带的模版文件
查看>>
hdu2874 LCA
查看>>
fedora中丢失或损坏fstab,无法启动,如何补救
查看>>
JAVA基本算法面试题:1斐波纳契数列
查看>>
GPU Memory Usage占满而GPU-Util却为0的调试
查看>>
iOS开发-UITapGestureRecognizer手势
查看>>
Java中的Lambda表达式
查看>>
Android中数据存储之SharedPreferences
查看>>
查询oracle中所有用户信息
查看>>
PHP数字价格格式化,保留两位小数
查看>>
MVC3.0入门学习笔记--Razor 之样式加载方式1
查看>>
Linux下LDAPSearch的例子
查看>>
创建指定大小的文件
查看>>
Java将byte[]和int的互相转换
查看>>
10.1-10.2泛型算法
查看>>
【转】Objective-C学习笔记四:循环结构
查看>>
JavaBeans 中添加 private static final long serialVersionUID = 1L
查看>>
ORACLE RAC集群硬件资源管理与单节点的区别
查看>>
洛谷 5061 秘密任务——二分图染色
查看>>
bzoj 2836 魔法树——树链剖分
查看>>