多线程之间的通信(等待唤醒机制、Lock 及其它线程的方法)
一、多线程之间的通信。
就是多个线程在操作同一份数据, 但是操作的方法不同。
如: 对于同一个存储块,其中有两个存储位:name sex, 现有两个线程,一个向其中存放数据,一个打印其中的数据。
为了解决上述问题中的安全问题(在存放线程进行存放操作的时候, 打印线程不能对共有数据进行操作),所以应当对两个线程
操作共有数据的代码部分进行同步(使用synchronized(),来进行同步, 注意 :使用同一个对象作为同步锁。
二、等待唤醒机制。
在上述案例实现过后运行,会发现:打印结果顺序并不是按照存放顺序进行的, 所以在此处就引入了等待唤醒机制。
解释:就是在一个线程进行了规定操作后,就进入等待状态(wait()), 等待其他线程执行完他们的指定代码过后 再将其唤醒(notify())。
在有多个线程进行等待时, 如果需要,可以使用 notifyAll()来唤醒所有的等待线程。
所使用的方法(关键字):
对象名.wait(); 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
对象名.notify(); 唤醒在此对象监视器上等待的单个线程。
对象名.notifyAll();唤醒在此对象监视器上等待的所有线程。
注意:以上方法(关键字),都必须使用在同步中,因为其需要对持有该对象监视器所有权(锁)的线程进行操作。
所以必须使用在同步中,因为只有同步中的线程才具有该对象监视器的所有权(锁),
wait()和sleep()一样,都会抛出 InterruptedException 异常。
而且,以上方法都定义在类:Object中
是因为,这些方法在操作同步中的线程的时候,都必须标示其所操作线程所持有的锁(被该锁的对象调用),
而只有同一个对象监视器下(同一个锁上的)的被等待线程,可以被持有该锁的线程唤醒,(无法唤醒不同锁上的线程)
即: 等待和唤醒的必须是同一个对象的监视器下(同一个锁上)的线程。
而锁可以是任意已近确定的对象, 能被任意对象调用的方法应当定义在 Object类中。
监视器(锁): 同一个对象的监视器下(同一个锁上)的线程,一次只能执行一个:就是拥有监视器所有权(持有锁)的那一个线程。
三、接口Lock和 接口Condition
注:在使用Lock 与Condition 时,必须引入其工具包:import java.util.concurrent.locks.*
在jdk1.5以上,为了解决多个线程同时在对一份共享数据进行不同操作时出现的安全问题(要么陷入所有线程同时等待的状态、
要么每次唤醒所有等待线程的问题),
其为我们提供了新的 锁工具: Lock来替换 synchronized , 由 Lock对象所创建的绑定于该Lock对象的 condition对象
替换了object类中的wait,notify操作。
1、Lock接口, 已知实现该接口的类: ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock
1)、 ReentrantLock(大体功能与 synchronized相当,不过可以绑定多个condition)
构造方法:ReentrantLock() 创建一个 ReentrantLock 的实例。
ReentrantLock(boolean fair) 创建一个具有给定公平策略的 ReentrantLock
常用方法: void lock() :获取一个锁。
void unlock() :释放该锁。
Condition newCondition() 返回用来与此 Lock 实例一起使用的 Condition 实例。
2、Contition接口, 已知实现类:AbstractQueuedLongSynchronizer.ConditionObject, AbstractQueuedSynchronizer.ConditionObject(暂时不学习)
常用方法:void await() 造成当前线程在接到信号或被中断之前一直处于等待状态。
void signal() 唤醒一个等待线程。
void signalAll() 唤醒所有等待线程。
常见代码示例:
class BoundedBuffer {
final Lock lock = new ReentrantLock(); //创建一个Lock的子类对象 lock
final Condition notFull = lock.newCondition(); //调用lock的newCondition方法,创建一个condition子类对象 notFull
final Condition notEmpty = lock.newCondition(); //调用lock的newCondition方法,创建一个condition子类对象 notEmpty
public void put(Object x) throws InterruptedException { //
lock.lock(); //获取锁
try {
while (判断语句)
notFull.await(); //判断成功,线程等待于notFull下。
操作代码
notEmpty.signal(); //唤醒notEmpty下的等待线程。
} finally { //保证其后语句执行。
lock.unlock(); //释放锁。
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while ()
notEmpty.await();
操作代码
notFull.signal();
} finally {
lock.unlock();
}
}
}
四、停止线程
注:在旧版本的jdk中存在stop方法,但是在新版本中。此方法被过时。
线程停止的原理: 当 run方法中的代码执行完毕过后,就自动停止该线程。
1、当线程中是循环代码的时候, 只要控制住循环结束,就能够结束该线程。
特殊情况:当线程中有wait()语句或者await()等语句时,会使得线程处于冻结状态, 让控制循环结束的代码或者标记无法执行或读取,
那么线程就不会结束。
当所有线程都陷入冻结,没有指定方法解除冻结时,就需要我们强制清除冻结状态,这样就可以操作标记使循环结束。
Thread类中提供了这一方法: Interrupt()方法,(等待型语句本身会有一个InterrptedException异常的判断,
只要被Interrupt方法打断冻结,就会抛出这一异常, 我们就可以在异常处理语句中建立循环结束的标记)。
五、守护线程
Thread类中有一个方法,调用该方法并传入 true ,能将该线程定义为 守护线程(后台线程),
该方法是: void setDaemon(boolean on) 将该线程标记为守护线程或用户线程。(调用时应当传入true)。
注意: 1、将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。
(就是说,后台线程依赖于前台线程)
2、该方法必须在启动线程前调用。
示例: Thread t = new Thread();
t.setDaemon(true);
t.start();
此时的线程 t 为守护线程。
六、Join方法。
vpi解释:void join() 等待该线程终止。
在线程A执行的时候,碰到了B线程.join方法时,A线程就会等待,等B线程执行完,才继续执行。
(当在调用join方法时传入参数: long millis 时,表示 A线程等待B线程执行时间最长为millis毫秒。)
join可以用来临时加入线程执行。
多线程之间的通信(等待唤醒机制、Lock 及其它线程的方法)的更多相关文章
- java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)
*java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时 ...
- java基础知识回顾之java Thread类学习(七)--java多线程通信等待唤醒机制(wait和notify,notifyAll)
1.wait和notify,notifyAll: wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以 ...
- Android-Java多线程通讯(生产者 消费者)&等待唤醒机制
多线程通讯:例如:有一个线程任务在run生产,还有一个线程任务在run消费: VIP尊贵的身份,生产者 消费者 方式,(精心生产制作一个超级无敌好吃的面包,卖给VIP尊贵的身份消费者)生产与消费 一对 ...
- java之等待唤醒机制(线程之间的通信)
线程间通信 概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同.比如:线程A用来生成包子的,线程B用来吃包子的,包子可以理解为同一资源,线程A与线程B处理的动作,一个是生产,一个是消 ...
- Java 之 线程 —线程通信( 等待唤醒机制)
一.线程间通信 概念:多个线程在处理同一资源,但是处理的动作(线程的任务)却不相同. 例如: 线程 A 用来生成包子的,线程 B 用来吃包子的,包子可以理解为同一资源,线程 A 与线程 B 处理的动作 ...
- Android-Java多线程通讯(生产者 消费者)&10条线程对-等待唤醒/机制的管理
上一篇博客 Android-Java多线程通讯(生产者 消费者)&等待唤醒机制 是两条线程(Thread-0 / Thread-1) 在被CPU随机切换执行: 而今天这篇博客是,在上一篇博客A ...
- 等待唤醒机制---Day25
线程间通信 概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同. 比如:线程A用来生成包子的,线程B用来吃包子的,包子可以理解为同一资源,线程A与线程B处理的动作,一个 是生产,一个 ...
- 等待唤醒机制----线程池----lambda表达式
1.等待唤醒机制 1.1线程间通信 概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同. 比如:线程A用来生成包子的,线程B用来吃包子的,包子可以理解为同一资源,线程A与线程B处理的 ...
- java多线程(死锁,lock接口,等待唤醒机制)
一.Lock接口 常用方法 Lock提供了一个更加面对对象的锁,在该锁中提供了更多的操作锁的功能. 使用Lock接口,以及其中的lock()方法和unlock()方法替代同步,对电影院卖票案例中Tic ...
随机推荐
- windows如何查看电脑开关机记录
如何查看电脑开关机记录 (一)如果你只是想查看一下,从昨天关机到今天开机之间有没有人使用我的计算机,在“开始”菜单的运行”中输入“eventvwr.msc”,或者是按下"开始菜单" ...
- 一个数据表通过另一个表更新数据(在UPDAT语句中使用FROM子句)
在sql server中,update可以根据一个表的信息去更新另一个表的信息. 首先看一下语法: update A SET 字段1=B表字段表达式, 字段2=B表字段表达式 from B WHE ...
- iOS APP 中H5视频默认全屏播放问题解决
问题描述:在Android中,视频可以正常在H5页面局部播放,iOS中则自动切换至全屏模式. 查看资料得以解决,20190301记录下来. 解决方法:IOS10及以后,在 video标签页中只包含 w ...
- JAVA程序设计 实验一报告
北京电子科技学院(BESTI) 实 验 报 告 课程:Java程序设计 班级:1351 姓名:李畅宇 学号:20135129 成绩: 指导教师:娄嘉鹏 ...
- 我的github地址 https://github.com/1010de/Test.git
构建之法老师叫交下任务学习github,经过一段时间的学习和了解,看介绍.看视频.看博客.初步认识到github的方便与好处. 自己试着去注册和使用github,已经慢慢学会了一些基本操作. ...
- TitleLayout——一个Android轻松实现通用、标准、支持沉浸式状态栏的标题栏库
TitleLayout 多功能.通用的.可在布局或者使用Java代码实现标题栏:支持沉浸式状态栏,支持左侧返回按钮(不需要手动实现页面返回),左侧支持图片+文字.图片.文字:右侧支持图片.文字等. 堆 ...
- windows下net命令失败
D:\apache-tomcat-7.0.57\bin>net start mysql57发生系统错误 5. 拒绝访问. 以管理员身份运行 run as administrator 打开cmd. ...
- mybatis批量插入和批量更新
批量插入数据使用的sql语句是: insert into table (aa,bb,cc) values(xx,xx,xx),(oo,oo,oo) mybatis中mapper.xml的代码如下: & ...
- Android控件第7类——对话框
1.AlertDialog AlertDialog用来生成对话框,功能十分强大. AlertDialog可以分成4个组成部分:标题栏上的图标,标题区,文本区,按钮区. 使用方法: 创建AlertDia ...
- ionic2中如何使用自动生成器
ionic generator是命令行的功能,ionic2自动帮我们创建应用程序,从而节省了大量的时间,并增加我们的速度来开发一个项目的关键部分. ionic generator使我们可以自动创建以下 ...