wait(),notify(),notifyAll()的理解与使用

这三个方法由于需要控制对对象的控制权(monitor),所以属于Object而不是属于线程。

wait(),会把持有该对象线程的对象控制权交出去,然后处于等待状态。

notify(),会通知某个正在等待这个对象的控制权的线程可以继续运行。

nofifyAll(),会通知所有等待这个对象控制权的线程继续运行,如果有多个正在等待该对象控制权时,具体唤醒哪个线程,就由操作系统进行调度。

注意:

1.生产者,消费者必须要对同一份资源进行操作。

2.无论是执行对象的wait、notify还是notifyAll方法,必须保证当前运行的线程取得了该对象的控制权(monitor)

生产者:

package com.currentPro.waitAndnotify;

import java.util.ArrayList;
import java.util.List;

public class Producer implements Runnable{

    private List<Integer> taskQueue = new ArrayList<Integer>();

    //生产的量
    private final int MAX_CAPACITY;

    public Producer(List<Integer> sharedQueue,int size){
        this.taskQueue = sharedQueue;
        this.MAX_CAPACITY = size;
    }

    @Override
       public void run()
       {
          int counter = 1;
          while (true)
          {
             try
             {
               synchronized (taskQueue)
                     {
                        while (taskQueue.size() == MAX_CAPACITY)
                        {
                           System.out.println("Queue is full " + Thread.currentThread().getName() + " is waiting , size: " + taskQueue.size());
                           taskQueue.wait();
                        }
                        Thread.sleep(1000);
                        taskQueue.add(counter);
                        System.out.println("Produced: " + counter);
                        counter++;
                        //唤醒正在等待的消费者,但是消费者是不是能获取到资源,由系统调度。
                        taskQueue.notifyAll();
                     }
             }
             catch (InterruptedException ex)
             {
                ex.printStackTrace();
             }
          }
       }

}

消费者:

package com.currentPro.waitAndnotify;

import java.util.List;

public class Consumer implements Runnable{

    private final List<Integer> taskQueue ;

    public Consumer(List<Integer> sharedQueue){
        this.taskQueue = sharedQueue;
    }

    @Override
       public void run()
       {
          while (true)
          {
             try
             {
                 synchronized (taskQueue)
                     {
                        while (taskQueue.isEmpty())
                        {
                           System.out.println("Queue is empty " + Thread.currentThread().getName() + " is waiting , size: " + taskQueue.size());
                           taskQueue.wait();
                        }
                        Thread.sleep(1000);
                        int i = (Integer) taskQueue.remove(0);
                        System.out.println("Consumed: " + i);
                        taskQueue.notifyAll();
                     }
             } catch (InterruptedException ex)
             {
                ex.printStackTrace();
             }
          }
       }
}

测试代码:

package com.currentPro.waitAndnotify;

import java.util.ArrayList;
import java.util.List;

public class Test {

    public static void main(String[] args) throws InterruptedException {
        //共享资源
        List<Integer> taskQueue = new ArrayList<Integer>();

        int MAX_CAPACITY = 5;
        //创建生产者线程
        Thread producer = new Thread(new Producer(taskQueue,MAX_CAPACITY),"producer");

        //创建消费者线程
        Thread consumer = new Thread(new Consumer(taskQueue),"consumer");

        consumer.start();
        Thread.sleep(2000);
        producer.start();

    }
}

参考资料

http://longdick.iteye.com/blog/453615

http://howtodoinjava.com/core-java/multi-threading/how-to-work-with-wait-notify-and-notifyall-in-java/

http://www.cnblogs.com/dolphin0520/p/3920385.html

时间: 2024-07-30 01:05:03

wait(),notify(),notifyAll()的理解与使用的相关文章

Java Object 对象上的wait(),notify(),notifyAll()方法理解

第一阶段理解(2017-7-27): Java 将wait(),notify(),notifyAll()方法放在Object对象上,也就是说任何一个对象都可以调用这个方法,这与”任何一个对象都有一个内置锁,可以用于线程同步“是照应的.因此,当某个线程要释放cpu争夺权,让自己进入等待状态时,调用 某个锁(对象)上的wait()方法,也就是让当前线程等待其它线程调用该锁上的notify()或notify()方法.线程间通过同步锁来实现等待与唤醒协作.简单例子: 1 package com.lyyc

Java Object对象中的wait,notify,notifyAll的理解

wait,notify,notifyAll 是定义在Object类的实例方法,用于控制线程状态,在线程协作时,大家都会用到notify()或者notifyAll()方法,其中wait与notify是java同步机制中重要的组成部分,需要结合与synchronized关键字才能使用,在调用一个Object的wait与notify/notifyAll的时候,必须保证调用代码对该Object是同步的,也就是说必须在作用等同于synchronized(object){......}的内部才能够去调用ob

java wait(),notify(),notifyAll()的理解

这个三个函数来自Object类,众所周知它们是用于多线程同步的.然而,有个问题却一直没搞清楚,即notify()函数到底通知谁?<Thinking in JAVA>中有这么一句话,当notify()函数因为某个特定锁被调用时,只有等待这个锁的任务才会被唤醒.什么意思? 看下面的代码,这个代码执行的话会报错,java.lang.IllegalMonitorStateException 上网查了一下,明白了. 1>当前线程不含有当前对象的锁资源的时候,调用obj.wait()方法;2>

线程问题3(synchronized,wait,notify,notifyAll,类锁,对象锁)

/** * 知识一: * 实现线程,有两种方法,一种是继承Thread类,一种是实现Runnable接口. * 本文推荐实现Runnable接口的方法. * 1.把需要共享的数据(可以是静态的,非静态的变量了)放在一个实现Runnable * 接口的类里面,然后把这个类的实例传给多个Thread的构造方法.这样,新创建 * 的多个Thread,都共同拥有一个Runnable实例,共享同一份数据. * 2.如果采用继承Thread类的方法,就只好使用static静态成员了. * 如果共享的数据比较

JAVA线程间协作:wait.notify.notifyAll

JAVA的进程同步是通过synchronized()来实现的,须要说明的是,JAVA的synchronized()方法相似于操作系统概念中的相互排斥内存块.在JAVA中的Object类型中.都是带有一个内存锁的,在有线程获取该内存锁后.其它线程无法訪问该内存.从而实现JAVA中简单的同步.相互排斥操作. 明确这个原理.就能理解为什么synchronized(this)与synchronized(static XXX)的差别了.synchronized就是针对内存区块申请内存锁,thiskeywo

Java 多线程 :入门(2)- 线程间协作:挂起当前线程(wait)与通知其他线程继续执行(notify\ notifyAll)

首先,之前我理解起来比较混沌的是到底谁是‘锁’这个问题,因为线程间协作的核心就是锁的交换,通过每个线程的“获得锁”与“释放锁”来实现. 锁,也叫“互斥”,是一种机制,通过控制一个对象在一定代码段(或方法内)同时只能被一个线程所访问,来实现所谓的(对于这个特定对象的)“线程安全”. 1.先看一个从网上扒来的最基本款示例,原文 http://www.cnphp6.com/archives/62258,写的很棒很清晰,我这里略微改了一两句: public class TestNotifyByFlag

wait() ,notify() ,notifyAll(),synchronized 和同步方法锁,对象锁的联系,关系,区别;

一直不明白一个问题,因为在书上关于生产者和消费者的例子里看到一段这样的代码,估计很多人都和我一样迷惑 1 public synchronized void set(String name, String content) { 2 if (!flag) { 3 try { 4 super.wait(); 5 } catch (InterruptedException e) { 6 e.printStackTrace(); 7 } 8 this.setNme(name); 9 ....... 10

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

1.wait和notify,notifyAll: wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以可以被任意对象调用的方法,定义在Object基类中. wait()方法:对此对象调用wait方法导致本线程放弃对象锁,让线程处于冻结状态,进入等待线程的线程池当中.wait是指已经进入同步锁的线程,让自己暂时让出同步锁,以便使其他正在等待此锁的线程可以进入同步锁并运行,只有其它线程调用notify方

wait()和notify()/notifyAll()

http://www.cnblogs.com/xrq730/p/4853932.html 轮询 线程本身是操作系统中独立的个体,但是线程与线程之间不是独立的个体,因为它们彼此之间要相互通信和协作. 想像一个场景,A线程做int型变量i的累加操作,B线程等待i到了10000就打印出i,怎么处理?一个办法就是,B线程while(i == 10000),这样两个线程之间就有了通信,B线程不断通过轮训来检测i == 10000这个条件. 这样可以实现我们的需求,但是也带来了问题:CPU把资源浪费了B线程