Java 之多线程通信(等待/唤醒)
多线程间通信: 多个线程在处理同一个资源, 但是任务却不同.
等待/唤醒机制
- 涉及的方法
- wait(): 让线程处于冻结状态, 被 wait() 的线程会被存储到线程池中
- notify(): 唤醒线程池中的任意一个线程
- notifyAll(): 唤醒线程池中所有的线程
 
- 这些方法必须定义在同步中, 因为这些方法是用于操作线程状态的方法, 必须要明确到底
 操作的是哪个锁上的线程.
- 为什么操作线程的方法 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 之多线程通信(等待/唤醒)的更多相关文章
- Java 实现多线程切换等待唤醒交替打印奇偶数
		引言 在日常工作生活中,可能会有用时几个人或是很多人干同一件事,在java编程中,同样也会出现类似的情况,多个线程干同样一个活儿,比如火车站买票系统不能多个人买一到的是同一张票,当某个窗口(线程)在卖 ... 
- java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)
		*java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时 ... 
- java基础知识回顾之java Thread类学习(七)--java多线程通信等待唤醒机制(wait和notify,notifyAll)
		1.wait和notify,notifyAll: wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以 ... 
- java 22 - 17 多线程之等待唤醒机制(接16)
		先来一张图,看看什么叫做等待唤醒机制 接上一章的例子. 例子:学生信息的录入和获取 * 资源类:Student * 设置学生数据:SetThread(生产者) * 获取学生数据:GetThread( ... 
- Java第二十五天,多线程之等待唤醒机制
		当线程被创建并且被启动之后,它既不是一启动就进入了执行状态,也不是一直处于执行状态,而是具有以下多种状态: 这六种状态之间的转换关系如下: 1.等待唤醒机制 注意: (1)两个线程之间必须用同步代码块 ... 
- java多线程的等待唤醒机制及如何解决同步过程中的安全问题
		/* class Person{ String name; String sex; boolean flag = true; public void setPerson(String name, St ... 
- Java 线程间通信 —— 等待 / 通知机制
		本文部分摘自<Java 并发编程的艺术> volatile 和 synchronize 关键字 每个处于运行状态的线程,如果仅仅是孤立地运行,那么它产生的作用很小,如果多个线程能够相互配合 ... 
- Java中的等待唤醒机制—至少50%的工程师还没掌握!
		这是一篇走心的填坑笔记,自学Java的几年总是在不断学习新的技术,一路走来发现自己踩坑无数,而填上的坑却屈指可数.突然发现,有时候真的不是几年工作经验的问题,有些东西即使工作十年,没有用心去学习过也不 ... 
- 多线程之Java中的等待唤醒机制
		多线程的问题中的经典问题是生产者和消费者的问题,就是如何让线程有序的进行执行,获取CPU执行时间片的过程是随机的,如何能够让线程有序的进行,Java中提供了等待唤醒机制很好的解决了这个问题! 生产者消 ... 
随机推荐
- 又开一坑,运动图形MoGraph for Unity
			Fragment+random: Vertex+random, Vertex+plain Vertex+Sound Plexus like 写了个大概,暂时没这方面需求先放这边了. C4D原版片段和克 ... 
- 新型I/O架构引领存储之变(二)
			新型I/O架构引领存储之变(二) 作者:廖恒 众所周知,支持存储及网络I/O服务的接口协议有很多种.比方,以太网及Infiniband接口都支持採用iSCSI协议来实现存储业务,它们也因而成为了ser ... 
- C++语言基础(20)-模板的非类型参数
			一.在函数模板中使用非类型参数 #include <iostream> using namespace std; template<class T> void Swap(T & ... 
- ASP.NET Web API 使用Swagger生成在线帮助测试文档,支持多个GET
			以下为教程: 在现有webapi项目中,nuget安装以下两个插件 swagger.net.ui swashbuckle 安装完毕后可以卸载Swagger.NET,此处不需要! 安装完毕后屏蔽以下代码 ... 
- c++ friend 遇到 namespace 无法访问 private 成员的问题
			相关的文章(比较有意思,记录一下):http://www.cnblogs.com/lx20030303/archive/2012/09/21/2696258.html 先看例子.如下. 尝试编译的话, ... 
- word中特殊符号的替换
			首先在word里替换快捷键是ctrl+H,点击“更多”,会出现更多选项,在特殊格式那里可以选在各种符号,比如回车,空格什么的. 有的时候在word里看不到一些格式,需要点一下下图的对着的两个箭头图标: ... 
- a5调试
			1 generating rsa key...[ 4.452000] mmc0: error -110 whilst initialising SD card[ 5.602000] mmc ... 
- 基于nginx的token认证
			Nginx 的 token 认证是基于集成了 nginx+lua 的 openresty 来实现的. 环境: centos 7 部署方式: 增量部署(不影响原 nginx 版本) 版本: openre ... 
- css3 一个简单的静态立方体
			<meta charset="utf8"> <style> .cube { position: absolute; left: 50%; top: 250p ... 
- Could not load type ‘System.ServiceModel.Activation.HttpModule’ from&
			1. 部署网站到IIS7.5,Window 2008的时候出现这个错误 2. 错误信息 Server Error in ‘/’ Application. Could not load type ‘ ... 
