先来一张图,看看什么叫做等待唤醒机制

接上一章的例子。

例子:学生信息的录入和获取

  * 资源类: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)的更多相关文章

  1. java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)

     *java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时 ...

  2. java基础知识回顾之java Thread类学习(七)--java多线程通信等待唤醒机制(wait和notify,notifyAll)

    1.wait和notify,notifyAll: wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以 ...

  3. Java第二十五天,多线程之等待唤醒机制

    当线程被创建并且被启动之后,它既不是一启动就进入了执行状态,也不是一直处于执行状态,而是具有以下多种状态: 这六种状态之间的转换关系如下: 1.等待唤醒机制 注意: (1)两个线程之间必须用同步代码块 ...

  4. java多线程的等待唤醒机制及如何解决同步过程中的安全问题

    /* class Person{ String name; String sex; boolean flag = true; public void setPerson(String name, St ...

  5. java多线程中的生产者与消费者之等待唤醒机制@Version1.0

    一.生产者消费者模式的学生类成员变量生产与消费demo,第一版1.等待唤醒:    Object类中提供了三个方法:    wait():等待    notify():唤醒单个线程    notify ...

  6. JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制

    JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是clas ...

  7. Java多线程02(线程安全、线程同步、等待唤醒机制)

    Java多线程2(线程安全.线程同步.等待唤醒机制.单例设计模式) 1.线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量 ...

  8. “全栈2019”Java多线程第三十二章:显式锁Lock等待唤醒机制详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  9. “全栈2019”Java多线程第二十四章:等待唤醒机制详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

随机推荐

  1. Maven版本与JDK版本

    http://maven.apache.org/docs/history.html

  2. VMware: XXX is still busy. Please wait until the operation is complete before closing

      在使用vmware的过程中发现创建快照.恢复快照.管理快照等功能突然都变成灰色的,用不了.更觉得夸张的是仅仅剩下关闭虚机按钮是红色的.心想估计是虚机快照没处理完之类的问题导致的,于是想想关闭虚机重 ...

  3. 你真的了解UIScrollView吗?

    一:首先查看一下关于UIScrollView的定义 NS_CLASS_AVAILABLE_IOS(2_0) @interface UIScrollView : UIView <NSCoding& ...

  4. objective-c系列-@Property&点语法

    //解释 property后边的圆括号中的修饰词的含义: //          nonatomic  非线程安全  非原子操作  特点是: 操作变量的效率高 //          atomic   ...

  5. 深入.net(继承)

    继承.多态,学习目标: 1.能够熟记定义和概念 2.能够理解其内部意义 3.能够运用到自己的编码实现中 如何进行代码的复用: ----- 自己写好了一段代码,理想状态(永远都不要再写了,直接用) -- ...

  6. 【代码笔记】iOS-点击搜索按钮,或放大镜后都会弹出搜索框

    一, 效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> #import "CLHSearchBar.h ...

  7. sublime mac osx 命令行打开

    sudo ln -s /Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl /usr/bin/subl 参考地址:htt ...

  8. nginx 的信号控制概述

    <nginx 在ubuntu 上的启动,停止,重启>中的停止和重启命令基本都是用信号来控制的.这是一些简单的信号控制. 在Nginx服务器中,通常情况都是通过对其发送控制信号进行控制的,除 ...

  9. Puppet权威指南

    <Puppet权威指南>基本信息作者: 王冬生 丛书名: Linux/Unix技术丛书出版社:机械工业出版社ISBN:9787111485988上架时间:2014-12-25出版日期:20 ...

  10. Windows Phone Studio-任何人都能开发Windows Phone App的在线工具

    在一段时间的内测以后,微软于今天早些时候发布了其Windows Phone应用开发的在线工具,名字叫做Windows Phone Studio.其意义在于,通过简单的内容添加和样式选择,实现Windo ...