java 22 - 17 多线程之等待唤醒机制(接16)
先来一张图,看看什么叫做等待唤醒机制

接上一章的例子。
例子:学生信息的录入和获取
* 资源类:Student
* 设置学生数据:SetThread(生产者)
* 获取学生数据:GetThread(消费者)
* 测试类:StudentDemo
* 资源类:Student (为了使用等待唤醒机制,添加了个布尔类型的变量,默认为flase)
public class Student {
String name;
int age;
boolean flag; // 默认情况是没有数据,如果是true,说明有数据
}
* 设置学生数据:SetThread(生产者)
public class SetThread implements Runnable {
private Student s;
private int x = 0;
public SetThread(Student s) {
this.s = s;
}
@Override
public void run() {
while (true) {
synchronized (s) {
//判断有没有
if(s.flag){
try {
s.wait(); //t1等着,释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (x % 2 == 0) {
s.name = "张三";
s.age = 23;
} else {
s.name = "李四";
s.age = 24;
}
x++; //x=1
//修改标记
s.flag = true;
//唤醒线程
s.notify(); //唤醒t2,唤醒并不表示你立马可以执行,必须还得抢CPU的执行权。
}
//t1有,或者t2有
}
}
}
* 获取学生数据:GetThread(消费者)
public class GetThread implements Runnable {
private Student s;
public GetThread(Student s) {
this.s = s;
}
@Override
public void run() {
while (true) {
synchronized (s) {
if(!s.flag){
try {
s.wait(); //t2就等待了。立即释放锁。将来醒过来的时候,是从这里醒过来的时候
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(s.name + "---" + s.age);
//张三---23
//李四---24
//修改标记
s.flag = false;
//唤醒线程
s.notify(); //唤醒t1
}
}
}
}
* 测试类:StudentDemo
public class StudentDemo {
public static void main(String[] args) {
//创建资源
Student s = new Student();
//设置和获取的类
SetThread st = new SetThread(s);
GetThread gt = new GetThread(s);
//线程类
Thread t1 = new Thread(st);
Thread t2 = new Thread(gt);
//启动线程
t1.start();
t2.start();
}
}
来,依次分析这段代码:
①假设消费者GetThread先抢到了CPU的资源:
则先执行这段代码:
public void run() {
while (true) { //true,进来
synchronized (s) {
if(!s.flag){ //因为是消费者先进来,所以里面没有“包子”,而s.flag的默认值是flase,这里取反,就true,进来
try {
s.wait(); //没“包子”,等待,并且释放锁。下次唤醒它的时候,是从这里唤醒,并不是从头开始执行
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(s.name + "---" + s.age);
s.flag = false;
s.notify();
}
}
}
②由于消费者在等待,并且释放了锁。则消费者和生产者继续抢CPU的资源,而消费者抢到的话,依旧等待,直到生产者(SetThread)抢到CPU的资源:
public void run() {
while (true) {
synchronized (s) {
if(s.flag){//判断有没有“包子”,这时候是没有的,s.flag = false,执行下面的if语句
try {
s.wait(); //t1等着,释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//首先x = 0,先录入张三
if (x % 2 == 0) {
s.name = "张三";
s.age = 23;
} else {
s.name = "李四";
s.age = 24;
}
x++; //x=1
//这时候已经有“包子”了,就修改标志
s.flag = true;
//唤醒线程
s.notify(); //唤醒t2,唤醒并不表示你立马可以执行,必须还得抢CPU的执行权。
}
//t1继续抢到执行权,或者t2抢到执行权
}
}
③若是t1继续抢到执行权:
synchronized (s) {
if(s.flag){//这个时候已经有了张三这个“包子”,而且flag = true;,所以进来
try {
s.wait(); //t1等待,并且释放锁,t1和t2抢占CPU资源,t1抢到继续等待,t2抢到就执行t2
} catch (InterruptedException e) {
e.printStackTrace();
}
}
④t2抢到执行权:
1 public void run() {
2 while (true) { //true,进来
3 synchronized (s) {
4 if(!s.flag){ //有“包子”,这时候的flag = true ,!s.flag = flase;不进来
5 try {
6 s.wait();
7 } catch (InterruptedException e) {
8 e.printStackTrace();
9 }
10 }
11 //消费“包子”
12 System.out.println(s.name + "---" + s.age);
13
14 //修改标记
15 s.flag = false;
16 //唤醒线程t1
17 s.notify();
18 }
//唤醒t1,唤醒并不表示你立马可以执行,必须还得抢CPU的执行权。
19 }
20 }
java 22 - 17 多线程之等待唤醒机制(接16)的更多相关文章
- java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)
*java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时 ...
- java基础知识回顾之java Thread类学习(七)--java多线程通信等待唤醒机制(wait和notify,notifyAll)
1.wait和notify,notifyAll: wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以 ...
- Java第二十五天,多线程之等待唤醒机制
当线程被创建并且被启动之后,它既不是一启动就进入了执行状态,也不是一直处于执行状态,而是具有以下多种状态: 这六种状态之间的转换关系如下: 1.等待唤醒机制 注意: (1)两个线程之间必须用同步代码块 ...
- java多线程的等待唤醒机制及如何解决同步过程中的安全问题
/* class Person{ String name; String sex; boolean flag = true; public void setPerson(String name, St ...
- java多线程中的生产者与消费者之等待唤醒机制@Version1.0
一.生产者消费者模式的学生类成员变量生产与消费demo,第一版1.等待唤醒: Object类中提供了三个方法: wait():等待 notify():唤醒单个线程 notify ...
- JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制
JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是clas ...
- Java多线程02(线程安全、线程同步、等待唤醒机制)
Java多线程2(线程安全.线程同步.等待唤醒机制.单例设计模式) 1.线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量 ...
- “全栈2019”Java多线程第三十二章:显式锁Lock等待唤醒机制详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java多线程第二十四章:等待唤醒机制详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
随机推荐
- 1分钟实现Autodesk Vault登录对话框
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courie ...
- iOS自定义字体
1.下载字体库,如:DINCond-Bold.otf 2.双击,在mac上安装 3.把下载的字体库拖入工程中: 4.配置info.plist文件 5.xib方式设置自定义字体:Font选Custom, ...
- 【代码笔记】iOS-带输入框的UIAlertView
一,效果图. 二,代码. //点击任何处,弹出输入框 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ UIAlertV ...
- OC NSFileManager(文件路径操作)
OC NSFileManager(文件路径操作) 初始化 NSFileManager * fm = [NSFileManager defaultManager]; 获取当前目录 [fm current ...
- BitTorrent Sync - 神奇的文件同步软件,无需服务器让多台电脑互相同步!
176,487 微博 腾讯 空间 微信 141 49 如今人们对文件备份和同步的需求已经越来越强烈了.像 Dropbox 一样的云存储网盘有很多,但它们都有一个局限性,就是所有的文件都得经过它们的服务 ...
- nutz如何体现mvc思想的
如何理解web mvc框架?? 一.没有使用mvc框架之前我们都是自己根据mvc分层思想的理解去把它物理化,比如:根据包的命名,根据类的后缀名,根据文件夹的命名去定义分层. 因为每个人对mvc的理解不 ...
- Unbuntu_14.04编译openjdk7
今天有问题需要研究一下JVM,但系统挂了,只能重装.在ubuntu下再次编译JDK,大约2个半小时,将遇到的问题笔记整理一下. 1.下载Openjdk Source Code 我用的是http://d ...
- ORACLE AWR报告数据的导入导出实践
关于AWR的快照数据可以导出.导入,一直没有亲手实践过.今天动手测试了一下如何导出.导入AWR数据,将AWR的数据从一测试服务器,导入到另外一台测试服务器. SQL> @?/rdbms/admi ...
- 将一列包含多个ID拆分多行
看到个不常见的问题~然后在 Inner Sql Server2008 里面找到一个思路. 如果下面的表结构,如何拆分多行并对应员工号呢? 首先创建测试表 CREATE TABLE Department ...
- c# winform插件
插件接口 namespace IMsg { ///<summary> /// 这是插件必须实现的接口,也是主程序与插件通信的唯一接口 /// 换句话说,主程序只认识插件里的这些方法 /// ...