这是一个关于生产者和消费者的线程通信的例子:

package thread_test;

public class PCThread {

    public static void main(String[] args) {
Queue q = new Queue();
Producer p = new Producer(q);
Consumer c = new Consumer(q);
p.start();
c.start();
}
}
//被唤醒后的线程到底重新执行同步代码块还是从那是等待的那里继续执行
class Producer extends Thread{
Queue q; Producer(Queue q){
this.q = q;
} public void run() {
for(int i = 1 ; i < 5 ; i ++) {
q.put(i);
}
}
} class Consumer extends Thread{
Queue q;
Consumer(Queue q){
this.q = q;
} public void run() {
while(true) {
q.get();
}
}
} class Queue{
int value = 0;
boolean isEmpty = true; public synchronized void put(int v) {
//如果共享数据没有被消费,则生产者等待
if(!isEmpty) {
try {
System.out.println("生产者等待");
wait();
}catch(Exception e) { }
}
value += v;
isEmpty = false;
System.out.println("生产者生产数量:" + v);
notify(); } public synchronized int get() {
if(isEmpty) {
try {
System.out.println("消费者等待");
wait();
}catch(Exception e) { }
}
value --;
if(value < 1) {
isEmpty = true;
}
System.out.println("消费者消费一个,剩余:" + value);
notify();
return value;
}
}

执行结果:

  我想不通为什么当消费者消费了一个之后,已经触发了notify(),为什么生产者没有开始生产,而是知道剩余为0 时才继续生产?

  这个问题我居然想了好久。。。

原因:

  notify/notifyAll() 的执行只是唤醒沉睡的线程,而不会立即释放锁。消费者消费一个产品后触发了notify()但此时这个消费者线程并没有释放锁,这个时候生产者线程虽然被唤醒,但是由于没有得到锁,仍然不能继续执行。

  当剩余商品为0 时,isEmpty为true,消费者线程执行到了wait()方法,这时候当前的锁被释放,消费者线程让出CPU,进入等待状态。被唤醒的生产者线程拿到了这个锁,继续执行自己的线程。

java——线程的wait()和notify()的更多相关文章

  1. Java线程通信——wait() 和 notify()

    Object类中有关线程通信的方法有两个notify方法和三个wait方法,官方解释: void notify() Wakes up a single thread that is waiting o ...

  2. java 线程之间通信以及notify与notifyAll区别。

    jvm多个线程间的通信是通过 线程的锁.条件语句.以及wait().notify()/notifyAll组成. 下面来实现一个启用多个线程来循环的输出两个不同的语句. package com.app. ...

  3. JAVA 线程状态以及synchronized,wait,sleep,yield,notify,notifyAll

    java线程存在以下几种状态: 1: 创建状态(New):线程被new出来,还未调用start 2: 就绪状态(Runnable):又称为可执行状态,调用线程的start方法后,线程处于就绪状态,,线 ...

  4. java线程中的sleep/wait/notify/yield/interrupt方法 整理

    java线程中的sleep/wait/notify/yield/interrupt方法 sleep 该方法能够使当前线程休眠一段时间 休眠期间,不释放锁 休眠时间结束之后,进入可执行状态,加入到线程就 ...

  5. (删)Java线程同步实现一:synchronzied和wait()/notify()

    上面文章(2.Java多线程总结系列:Java的线程控制实现)讲到了如何对线程进行控制,其中有一个是线程同步问题.下面我们先来看一个例子: 1.一个典型的Java线程安全例子 package com. ...

  6. 【java线程系列】java线程系列之线程间的交互wait()/notify()/notifyAll()及生产者与消费者模型

    关于线程,博主写过java线程详解基本上把java线程的基础知识都讲解到位了,但是那还远远不够,多线程的存在就是为了让多个线程去协作来完成某一具体任务,比如生产者与消费者模型,因此了解线程间的协作是非 ...

  7. 【Java 线程的深入研究3】最简单实例说明wait、notify、notifyAll的使用方法

    wait().notify().notifyAll()是三个定义在Object类里的方法,可以用来控制线程的状态. 这三个方法最终调用的都是jvm级的native方法.随着jvm运行平台的不同可能有些 ...

  8. Java多线程:线程状态以及wait(), notify(), notifyAll()

    一. 线程状态类型1. 新建状态(New):新创建了一个线程对象.2. 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中,变得可运 ...

  9. Java线程和多线程(二)——对象中的wait,notify以及notifyAll方法

    Java对象中的wait,notify以及notifyAll方法 在Java的Object类中包含了3个final的方法,这三个方法允许线程来交流资源是否被锁定.这三个方法就是wait(),notif ...

随机推荐

  1. python的argparse模块

    一.简介: argparse是python用于解析命令行参数和选项的标准模块,用于代替已经过时的optparse模块.argparse模块的作用是用于解析命令行参数,例如python parseTes ...

  2. R: 一页显示多张图的方法

    ################################################### 问题:一页多图显示   18.4.30 怎么实现,在一页上画多幅图,并且安排图的大小.个数等?? ...

  3. Entity Framework Tutorial Basics(23):Add Single Entity

    Add New Entity using DBContext in Disconnected Scenario: In this chapter you will learn how to add n ...

  4. jQuery 插件开发——PopupLayer(弹出层)

    导读:上次写了一篇关于GridView的插件开发方法,上几天由于工作需要,花了一天左右的事件封装了popupLayer(弹出层)插件.今天有时间就记录一下自己的开发思想与大家分享下,同时也算是对这段时 ...

  5. 微信创建带参数二维码,并加上logo

    现在需要创建一个场景二维码,除了基础的微信接口创建外,需要加上小logo,思路如下: 1. 首先根据微信的开发文档创建二维码,获取二维码的url,没啥可说的,按照文档来就好了 获取到的二维码就是这么素 ...

  6. 访问其他电脑的c盘

    访问其他电脑的c盘 \\192.168.0.1\C$

  7. 温故而知新_C语言_前缀++(--)和后缀++(--)

    前缀++(--)和后缀++(++)是有区别的. 再单独使用的时候是没有区别的,都是自身递增或者递减1. 但是综合使用起来会一样吗? 下面的例子都是++,替换成--也是一样,道理都是一样的. 请先看下面 ...

  8. idea 面板介绍

    一.面板说明 IDEA面板的全貌如下图 二.菜单栏 下面会简单介绍下一些常用的部分菜单使用,如有疑问或补充欢迎留言. (1).File文件 1. New:新建一个工程 可以新建project,导入已存 ...

  9. (原创)Codeforces Round #550 (Div. 3) A Diverse Strings

    A. Diverse Strings time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  10. kuangbin专题16D(next求最小循环节)

    题目链接: https://vjudge.net/contest/70325#problem/D 题意: 给出一个循环字符串, 可以在两端添加任意字符, 问最少添加多少字符可以使循环字符串变成周期循环 ...