body, table{font-family: 微软雅黑; font-size: 10pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}

线程间通信
█ 针对同一个资源的操作有不同的线程
      ☞ 举例:买点影票有卖出的,也有退票的
█ Demo
      ☞ 通过生产线程 和消费线程,对一个生产对象进行操作。

等待唤醒机制
█ Object

>Wait()       // 执行wait会自动释放锁     
>Notify()    //会唤醒其他等待进程,但是不会释放锁;通知其他进程可以执行,其他进程获得可以执行的一个条件进入同步阻塞,当进程获得锁的时候就进入就绪状态    
>notifyAll()

为什么不定义在Thread类中?
//因为锁可以是任意对象。若以线程间通信机制的api必须所有对象都有

线程状态转换图
Baozi.java TestMain.java
package com.java.thread_PV;
public class Baozi {
        private String name;
        private String price;
        private boolean flag;    //flag 为false的时候表示没有数据,为true表示有数据;不初始化默认为FALSE
        public String getName() {
                return name;
        }
        public void setName(String name) {
                this.name = name;
        }
        public String getPrice() {
                return price;
        }
        public void setPrice(String price) {
                this.price = price;
        }
        public Baozi(String name, String price) {
                super();
                this.name = name;
                this.price = price;
        }
        public boolean isFlag() {
                return flag;
        }
        public void setFlag(boolean flag) {
                this.flag = flag;
        }
}

package com.java.thread_PV;
public class TestMain {
        public static void main(String[] args) {
                Baozi baozi=new Baozi(null,null);    //同一个对象,后面确保同一把锁
                Producer producer=new Producer(baozi);
                Customer customer=new Customer(baozi);
                producer.start();
                customer.start();
        }
}

Producer.java Customer.java
package com.java.thread_PV;
public class Producer extends Thread {
        Baozi baozi;
        public Producer(Baozi baozi2) {
                baozi = baozi2;
        }
        public void run() {
                super.run();
                int i = 0;
                while (true) {
                        synchronized (baozi) {  //notify 和  wait 机制需要放到同步代码快里使用
                                if (baozi.isFlag()) {  // flag 为true表示有包子
                                        // 等待 (放弃执行权,让其他线程执行。消费者去消费)
                                        try {
                                                baozi.wait();
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }
                                }
                                // 没有包子就生产
                                if (i % 2 == 0) {
                                        baozi.setName("天津狗不理");
                                        baozi.setPrice("10RMB");
                                } else {
                                        baozi.setName("无锡灌汤包");
                                        baozi.setPrice("5RMB");
                                }
                                i++;
                                // 生产完之后?改变标记flag为true,通知消费者来消费
                                baozi.setFlag(true);
                                baozi.notify();   // 通知消费者,但是消费者并不能立即执行;要等后面的代码全部执行完释放锁后,消费者进程抢到锁才能执行
                        }
                }
        }
}
package com.java.thread_PV;
public class Customer extends Thread {
        Baozi baozi;
        public Customer(Baozi baozi2) {
                baozi = baozi2;
        }
        public void run() {
                super.run();
                while (true) {
                        synchronized (baozi) {
                                if (!baozi.isFlag()) { // false 表示没有包子,就等待
                                        try {
                                                baozi.wait();  //等待的时候放弃cpu执行权。。但是这里要释放锁!!这里wait方法会自动释放锁,所以不会形成死锁
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }
                                }
                                // 如果有就消费
                                System.out.println("Customer.consume()" + baozi.getName() + " :" + baozi.getPrice());
                                // 消费完就修改标记,通知生产者去生产
                                baozi.setFlag(false);
                                baozi.notify();  // 通知生产者,notify不会释放锁,如果下面还有代码,这里还会接着执行,不会释放锁;另外的进程不会拿到锁,会进入同步阻塞;拿到锁就进入就绪状态
                        }
                }
        }
}

Java——线程间通信的更多相关文章

  1. Java线程间通信-回调的实现方式

    Java线程间通信-回调的实现方式   Java线程间通信是非常复杂的问题的.线程间通信问题本质上是如何将与线程相关的变量或者对象传递给别的线程,从而实现交互.   比如举一个简单例子,有一个多线程的 ...

  2. Java线程间通信之wait/notify

    Java中的wait/notify/notifyAll可用来实现线程间通信,是Object类的方法,这三个方法都是native方法,是平台相关的,常用来实现生产者/消费者模式.我们来看下相关定义: w ...

  3. java线程间通信:一个小Demo完全搞懂

    版权声明:本文出自汪磊的博客,转载请务必注明出处. Java线程系列文章只是自己知识的总结梳理,都是最基础的玩意,已经掌握熟练的可以绕过. 一.从一个小Demo说起 上篇我们聊到了Java多线程的同步 ...

  4. 说说Java线程间通信

    序言 正文 [一] Java线程间如何通信? 线程间通信的目标是使线程间能够互相发送信号,包括如下几种方式: 1.通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值:线程A在 ...

  5. 说说 Java 线程间通信

    序言 正文 一.Java线程间如何通信? 线程间通信的目标是使线程间能够互相发送信号,包括如下几种方式: 1.通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值:线程A在一个 ...

  6. java线程间通信1--简单实例

    线程通信 一.线程间通信的条件 1.两个以上的线程访问同一块内存 2.线程同步,关键字 synchronized 二.线程间通信主要涉及的方法 wait(); ----> 用于阻塞进程 noti ...

  7. java线程间通信之通过管道进行通信

    管道流PipeStream是一种特殊的流,用于在不同线程间直接传送数据,而不需要借助临时文件之类的东西. jdk中提供了四个类来使线程间可以通信: 1)PipedInputStream和PipedOu ...

  8. Java——线程间通信问题

     wait和sleep区别: 1.wait可以指定时间可以不指定.     sleep必须指定时间. 2.在同步时,对cpu的执行权和锁的处理不同.     wait:释放执行权,释放锁.     ...

  9. Java线程间通信

    1.由来 当需要实现有顺序的执行多个线程的时候,就需要进行线程通信来保证 2.实现线程通信的方法 wait()方法: wait()方法:挂起当前线程,并释放共享资源的锁 notify()方法: not ...

随机推荐

  1. 终于在nowcoder爆发了的懒惰

    题目 这类题目我实在忍不了了 Emma,随便做个nowcode比赛题吧,我在oj上也没找到 题意 求\(\sum_{L=1}^{n}\sum_{R=i}^{n}a[k](L<=k<=R)\ ...

  2. POJ 2373 Dividing the Path (单调队列优化DP)题解

    思路: 设dp[i]为覆盖i所用的最小数量,那么dp[i] = min(dp[k] + 1),其中i - 2b <= k <= i -2a,所以可以手动开一个单调递增的队列,队首元素就是k ...

  3. HDU 1285 确定比赛名次(拓扑排序)题解

    Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委 ...

  4. 01_re正则表达式

    正则表达式,是一个特殊的字符串, 是对一类字符串的描述 ( 怎么描述一类字符: 普通字符+元字符+重复)检测给定的字符串,是否和正则表达式描述的字符串相匹配 举例:1) 检查一串数字是否是电话号码2) ...

  5. HDU 5884 Sort(二分+优先队列)

    http://acm.hdu.edu.cn/showproblem.php?pid=5884 题意:有个屌丝设计了一个程序,每次可以将k个数组进行合并,代价为这k个数组总的长度之和.现在另外一个屌丝要 ...

  6. UVa 1606 两亲性分子

    https://vjudge.net/problem/UVA-1606 题意:平面上有n个点,每个点为白点或者黑点.现在需放置一条隔板,使得隔板一侧的白点数加上另一侧的黑点数总数最大.隔板上的点可以看 ...

  7. Hibernate 由实体类与配置文件的配置关系生成数据库中的表

    import org.hibernate.cfg.Configuration; import org.hibernate.tool.hbm2ddl.SchemaExport; public class ...

  8. (转)c++一些知识点

    异常详解: https://www.cnblogs.com/hdk1993/p/4357541.html#top 模版详解: https://blog.csdn.net/lezardfu/articl ...

  9. Java设计模式(五)——适配器模式

    先举一个例子解释一下生活中的适配器模式:公司老总要求工程部经理来汇报一下公司内部的消防设备使用和维护情况.接到通知后,工程部经理老宋找了专门负责消防设备统计的维护人员小王,请他调出了去年全年的维护记录 ...

  10. 关于Dos命令中存在中文的解决方法

    问题:当我们直接打开dos窗口并在里面写入中文时是没有问题的,但是当我们把这些命令放在bat文件中执行时就出问题了解决:1.首先可以通过pause命令来查看错误原因2.记事本默认是UTF-8格式的,而 ...