多线程间通信: 多个线程在处理同一个资源, 但是任务却不同.

等待/唤醒机制

  1. 涉及的方法

    • wait(): 让线程处于冻结状态, 被 wait() 的线程会被存储到线程池中
    • notify(): 唤醒线程池中的任意一个线程
    • notifyAll(): 唤醒线程池中所有的线程
  2. 这些方法必须定义在同步中, 因为这些方法是用于操作线程状态的方法, 必须要明确到底

    操作的是哪个锁上的线程.
  3. 为什么操作线程的方法 wait(), notify(), notifyAll() 定义在了 Object 类中?

    因为这些方法是监视方法, 监视器其实就是锁. 而锁可以是任意的对象, 任意对象都能调用的方法一定

    定义在 Object 类中.

// 资源
class Resource
{
String name;
String sex;
boolean flag = false;
} // 输入线程
class Input implements Runnable
{
Resource r; // 带参数的构造函数, 以确保输入和输出操作的是同一个资源
Input(Resource r)
{
this.r = r;
} public void run()
{
int x = 0;
while(true)
{
synchronized(r)
{
if(r.flag)
//该异常只能捕获, 不能抛出, 因为父类 Runnable 中 run() 方法没有异常
try{r.wait();}catch(InterruptedException e){}
if(x==0)
{
r.name = "mike";
r.sex = "nan";
}
else
{
r.name = "丽丽";
r.sex = "girlgirlgirl";
}
r.flag = true;
r.notify();
}
x = (x+1)%2; // 改变 x 的值, 获得不同的输入值
}
}
} class Output implements Runnable
{
Resource r; // 带参数的构造函数, 确保输入和输出线程操作的是同一个资源
Output(Resource r)
{
this.r = r;
} public void run()
{
while(true)
{
synchronized(r) // 以资源对象作为锁, 输入线程和输出线程使用的为同一个锁
{
if(!r.flag)
try{r.wait();}catch(InterruptedException e){}
System.out.println(r.name + "......" + r.sex);
r.flag = flase;
r.notify();
}
}
}
} class ResourceDemo
{
public static void main(String[] args)
{
// 创建资源
Resource r = new Resource(); // 创建任务
Input in = new Input(r); // 使用带参数的构造函数初始化, 确保操作的为同一个资源 r
Output out = new Output(r); //使用带参数的构造函数初始化, 确保操作的为同一个资源 r // 创建线程
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
// 开启线程
t1.start();
t2.start(); }
} <--------------------分隔线--------------------------------->
// 将属性私有化, 升级版
class Resource
{
private String name;
private String sex;
private boolean flag = false; public synchronized void set(String name, String sex) //使用同步函数
{
if(flag)
try{this.wait();}catch(InterruptedException e){}
this.name = name;
this.sex = sex;
flag = true;
this.notify(); // 这时候的锁是 this
} public synchronized void out()
{
if(!flag)
try{this.wait();}catch(InterruptedException e){}
System.out.println(name+"....."+sex);
flag = false;
this.notify();
}
} class Input implements Runnable
{
Resource r; Input(Resource r)
{
this.r = r;
} public void run()
{
int x = 0;
while(true)
{
if(x==0)
{
r.set("mike","nan");
}
else
{
r.set("lili","nvnv");
}
x = (x+1)%2;
}
}
} class Output implements Runnable
{
Resource r;
Output(Resource r)
{
this.r = r;
} public void run()
{
while(true)
{
r.out();
}
}
}

- [JavaSE 基础视频(毕向东)](https://www.bilibili.com/video/av3106510/)

Java 之多线程通信(等待/唤醒)的更多相关文章

  1. Java 实现多线程切换等待唤醒交替打印奇偶数

    引言 在日常工作生活中,可能会有用时几个人或是很多人干同一件事,在java编程中,同样也会出现类似的情况,多个线程干同样一个活儿,比如火车站买票系统不能多个人买一到的是同一张票,当某个窗口(线程)在卖 ...

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

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

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

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

  4. java 22 - 17 多线程之等待唤醒机制(接16)

    先来一张图,看看什么叫做等待唤醒机制 接上一章的例子. 例子:学生信息的录入和获取 * 资源类:Student  * 设置学生数据:SetThread(生产者) * 获取学生数据:GetThread( ...

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

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

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

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

  7. Java 线程间通信 —— 等待 / 通知机制

    本文部分摘自<Java 并发编程的艺术> volatile 和 synchronize 关键字 每个处于运行状态的线程,如果仅仅是孤立地运行,那么它产生的作用很小,如果多个线程能够相互配合 ...

  8. Java中的等待唤醒机制—至少50%的工程师还没掌握!

    这是一篇走心的填坑笔记,自学Java的几年总是在不断学习新的技术,一路走来发现自己踩坑无数,而填上的坑却屈指可数.突然发现,有时候真的不是几年工作经验的问题,有些东西即使工作十年,没有用心去学习过也不 ...

  9. 多线程之Java中的等待唤醒机制

    多线程的问题中的经典问题是生产者和消费者的问题,就是如何让线程有序的进行执行,获取CPU执行时间片的过程是随机的,如何能够让线程有序的进行,Java中提供了等待唤醒机制很好的解决了这个问题! 生产者消 ...

随机推荐

  1. Atitit.设计模式-----触发器模式 trigger  详解

    Atitit.设计模式-----触发器模式 trigger  详解 1. 触发器概念1 1.1. 触发器位置 after|before|instead of1 2. 数据库里面的触发器1 2.1. o ...

  2. layui基础上的tree菜单动态渲染;

    var layout=[ { title:'脚本对象名称', treeNodes:true, headerClass:'value_col', colClass:'value_col', style: ...

  3. Oracle之比较NVARCHAR2字符串

    一.引言 昨天遇到一个问题,一直想不通是为什么,我在pl/sql里面执行sql语句,选出字段值等于某个值的的行: '; 用select * from test;是可以查到该值的,但是用这条语句却没有结 ...

  4. jquery ui 与 easy ui同时引入 展示效果冲突的问题

    jquery ui 由于在定位控件的时候跟easy UI 控件名相同,同时引入会导致冲突 如果需要两个都存在,可以去jquery ui下载定制版ui 脚本文件

  5. Oracle密码过期,取消密码180天限制

    1.进入sqlplus模式 sqlplus / as sysdba; 2.帐户再改一次密码 alter user 用户名 identified by 原密码; 3.查看用户密码的有效期设置(一般默认的 ...

  6. 逻辑漏洞-客户端验证的邮箱-Web渗透实例之中国教育部青少年普法网站逻辑漏洞

    转载自:http://www.zmnhssn.com/?post=61 漏洞地址:https://user.qspfw.com  用户登陆界面 具体漏洞地址:    用户密码找回界面:https:// ...

  7. 标准差分进化算法matlab程序实现(转载)

    标准差分进化算法matlab程序实现 自适应差分演化算法方面的Matlab和C++代码及论文 差分进化算法 DE-Differential Evolution matlab练习程序(差异演化DE) [ ...

  8. Vim 学习笔记二

    1. 粘帖 p 光标前 P 2. 撤销对撤销的撤销 Ctrl+r 3. dl:删除一个字符,daw:删除一个单词,dap:删除一个段落 4. 单个c字符并无效果,cc删除整个一行 C:从当前光标出删除 ...

  9. css 制作三角形图标 不支持IE6

    .triangle { width: 10px; height: 10px; overflow: hidden; border-left: 4px solid rgba(, , , ); border ...

  10. RTT第一个工程

    第一个RTT工程 1. 配置工程 选择芯片STM32F103C8(其包含该芯片的Flash及SRAM介绍): Jlink  SW模式 output->Debug info/Browse info ...