线程的等待唤醒机制

原创 2015年11月18日 17:52:13

( 1 )等待唤醒机制就是用于解决线程间通信的问题的,使用到的3个方法的含义如下:
wait:告诉当前线程放弃执行权,并放弃监视器(锁)并进入阻塞状态,直到其他线程持有获得执行权,并持有了相同的监视器(锁)并调用notify为止。
notify:唤醒持有同一个监视器(锁)中调用wait的第一个线程,例如,餐馆有空位置后,等候就餐最久的顾客最先入座。注意:被唤醒的线程是进入了可运行状态。等待cpu执行权。
notifyAll:唤醒持有同一监视器中调用wait的所有的线程。


( 2 )调用wait和notify方法需要注意的细节:
wait方法与notify方法必须要由同一个锁对象调用。因为:对应的锁对象可以通过notify唤醒使用同一个锁对象调用的wait方法后的线程。
wait方法与notify方法是属于Object类的方法的。因为:锁对象可以是任意对象,而任意对象的所属类都是继承了Object类的。
wait方法与notify方法必须要在同步代码块或者是同步函数中使用。因为:必须要通过锁对象调用这2个方法。

( 3 ) waite和sleep方法的区别
1.相同之处:
线程调用wait()或者是sleep()方法都会进入临时阻塞状态,会释放cpu的执行权。调用时都需要处理 InterruptedException异常。

2.不同之处:
wait(): 释放资源,释放锁。是Object的方法。
sleep():释放资源,不释放锁。是Thread的静态方法

下面通过例子来说明.
/**
 * 要实现的效果就是,有一个水池,水池的容量为50L,一个放水线程,负责放水,每200毫秒放出1L水,当水放完后,通知注水线程工作,同时放水线程停止工作;
 * 注水线程每200毫秒注水1L,水注满时,再通知放水线程继续工作,同时注水线程停止工作.
 * 
 * @author mChenys
 * 
 */
public class _Main5 {
	public static void main(String[] args) {
		Pool pool = new Pool();
		WaterIn in = new WaterIn(pool, "注水线程");
		WaterOut out = new WaterOut(pool, "放水线程");
		in.start();
		out.start();
	}
}

/**
 * 水池,容量为50L
 * 
 * @author mChenys
 * 
 */
class Pool {
	public int MAX_VLAUE = 50;
	public int curr_value = 0;
}

/**
 * 注水线程
 * 
 * @author mChenys
 * 
 */
class WaterIn extends Thread {
	private Pool pool;

	public WaterIn(Pool pool, String name) {
		super(name);
		this.pool = pool;
	}

	@Override
	public void run() {
		while (true) {
			synchronized (pool) {
				try {
					if (pool.curr_value < pool.MAX_VLAUE) {
						// 加水
						Thread.sleep(200);
						pool.curr_value += 1;
						System.out.println(this.getName() + "正在加水,加入 "
								+ pool.curr_value + " L水");
					} else if (pool.curr_value == pool.MAX_VLAUE) {

						System.out.println(this.getName()
								+ "水已加满!!,可以放水了......");
						pool.notify();// 唤醒放水线程
						pool.wait();// 当前线程等待,释放锁对象
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

/**
 * 放水线程
 * 
 * @author mChenys
 * 
 */
class WaterOut extends Thread {
	private Pool pool;

	public WaterOut(Pool pool, String name) {
		super(name);
		this.pool = pool;
	}

	@Override
	public void run() {
		while (true) {
			synchronized (pool) {
				try {
					if (pool.curr_value > 0) {
						// 放水
						Thread.sleep(200);
						pool.curr_value -= 1;
						System.out.println(this.getName() + "开始放水,放出 "
								+ (pool.MAX_VLAUE - pool.curr_value) + " L水");

					} else if (pool.curr_value == 0) {
						System.out.println(this.getName() + "水已放完,可以加水了.....");
						pool.notify();// 唤醒注水线程
						pool.wait();// 当前线程等待,释放锁对象
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

运行效果:
注水线程正在加水,加入 20 L水
注水线程正在加水,加入 40 L水
注水线程正在加水,加入 60 L水
注水线程正在加水,加入 80 L水
注水线程正在加水,加入 100 L水
注水线程正在加水,加入 120 L水
注水线程正在加水,加入 140 L水
注水线程正在加水,加入 160 L水
注水线程正在加水,加入 180 L水
注水线程正在加水,加入 200 L水
注水线程正在加水,加入 220 L水
注水线程正在加水,加入 240 L水
注水线程正在加水,加入 260 L水
注水线程正在加水,加入 280 L水
注水线程正在加水,加入 300 L水
注水线程正在加水,加入 320 L水
注水线程正在加水,加入 340 L水
注水线程正在加水,加入 360 L水
注水线程正在加水,加入 380 L水
注水线程正在加水,加入 400 L水
注水线程正在加水,加入 420 L水
注水线程正在加水,加入 440 L水
注水线程正在加水,加入 460 L水
注水线程正在加水,加入 480 L水
注水线程正在加水,加入 500 L水
注水线程水已加满!!,可以放水了......
放水线程开始放水,放出 20 L水
放水线程开始放水,放出 40 L水
放水线程开始放水,放出 60 L水
放水线程开始放水,放出 80 L水
放水线程开始放水,放出 100 L水
放水线程开始放水,放出 120 L水
放水线程开始放水,放出 140 L水
放水线程开始放水,放出 160 L水
放水线程开始放水,放出 180 L水
放水线程开始放水,放出 200 L水
放水线程开始放水,放出 220 L水
放水线程开始放水,放出 240 L水
放水线程开始放水,放出 260 L水
放水线程开始放水,放出 280 L水
放水线程开始放水,放出 300 L水
放水线程开始放水,放出 320 L水
放水线程开始放水,放出 340 L水
放水线程开始放水,放出 360 L水
放水线程开始放水,放出 380 L水
放水线程开始放水,放出 400 L水
放水线程开始放水,放出 420 L水
放水线程开始放水,放出 440 L水
放水线程开始放水,放出 460 L水
放水线程开始放水,放出 480 L水
放水线程开始放水,放出 500 L水
放水线程水已放完,可以加水了.....
注水线程正在加水,加入 20 L水
注水线程正在加水,加入 40 L水
注水线程正在加水,加入 60 L水
注水线程正在加水,加入 80 L水
注水线程正在加水,加入 100 L水
注水线程正在加水,加入 120 L水
注水线程正在加水,加入 140 L水
注水线程正在加水,加入 160 L水
注水线程正在加水,加入 180 L水
注水线程正在加水,加入 200 L水
注水线程正在加水,加入 220 L水
注水线程正在加水,加入 240 L水
注水线程正在加水,加入 260 L水
注水线程正在加水,加入 280 L水
注水线程正在加水,加入 300 L水
注水线程正在加水,加入 320 L水
注水线程正在加水,加入 340 L水
注水线程正在加水,加入 360 L水
注水线程正在加水,加入 380 L水
注水线程正在加水,加入 400 L水
注水线程正在加水,加入 420 L水
注水线程正在加水,加入 440 L水
注水线程正在加水,加入 460 L水
注水线程正在加水,加入 480 L水
注水线程正在加水,加入 500 L水
注水线程水已加满!!,可以放水了......
放水线程开始放水,放出 20 L水
放水线程开始放水,放出 40 L水
放水线程开始放水,放出 60 L水
放水线程开始放水,放出 80 L水
放水线程开始放水,放出 100 L水
放水线程开始放水,放出 120 L水
放水线程开始放水,放出 140 L水
放水线程开始放水,放出 160 L水
放水线程开始放水,放出 180 L水
放水线程开始放水,放出 200 L水




版权声明:本文为博主原创文章,未经博主允许不得转载。

第二部分 线程的等待和唤醒

从这个图中可以看出,等待状态是一种特殊的状态。使线程陷入等待实际上是暂时剥夺线程当前拥有的CPU时间片和获取CPU时间片的资格,使其返回到就绪状态。除非被唤醒,否则等待时间已满,该线程将一直等待。不会...
  • cuiran
  • cuiran
  • 2011年01月13日 14:24
  • 11441

Java线程唤醒与阻塞

阻塞指的是暂停一个线程的执行以等待某个条件发生(如某资源就绪),学过操作系统的同学对它一 定已经很熟悉了。Java 提供了大量方法来支持阻塞,下面让我们逐一分析。   1. sleep() 方...
  • Small____Fish
  • Small____Fish
  • 2012年07月08日 14:29
  • 18033

线程的等待与唤醒

当前线程在继续执行前需要等待一个条件,仅有synchornized关键字是不够的。虽然synchornized阻止并发访问一个对象,但是它没有实现线程中的通信。为此Object提供了notify(),...
  • jjarchu
  • jjarchu
  • 2015年11月25日 17:49
  • 868

线程的睡眠与唤醒

1.线程的睡眠与唤醒 public static void main(String[] args) { final Thread li = new Thread(){ ...
  • u011249702
  • u011249702
  • 2016年03月14日 15:42
  • 721

多线程等待唤醒机制:从wait()和sleep()的差别说起

1. wait():释放资源,释放锁 sleep():释放资源,不释放锁 wait():Object的方法,用在同步当中,是同步锁的方法,以锁控制线程 sleep():线程类Thread本身的静态...
  • ghbfgb
  • ghbfgb
  • 2016年11月13日 11:26
  • 1875

java 多线程等待、唤醒机制实例

例子: 1、实体类 public class Student {     String name;     int age;     boolean flag = false; // 表示没有值 } ...
  • helongzhong
  • helongzhong
  • 2016年10月26日 12:46
  • 1830

线程的7种状态及相互转换(图)以及关于线程同步(7种同步方式)

线程的7种状态及相互转换(图)以及关于线程同步(7种同步方式)
  • mine_song
  • mine_song
  • 2017年04月15日 15:01
  • 604

java 线程wait()与notify()的用法(被唤醒后的线程到底重新执行同步代码块还是从那是等待的那里继续执行)

java 线程wait()与notify()的用法(被唤醒后的线程到底重新执行同步代码块还是从那是等待的那里继续执行)   2013-09-24 22:15:58|  分类: java |举报...
  • hbgCSDN
  • hbgCSDN
  • 2014年12月05日 10:40
  • 7073

Java并发编程(二)线程同步和等待唤醒机制

概述线程安全是并发编程中的重要关注点,应该注意到的是,造成线程安全问题的主要原因有两点,一是存在共享数据(也称临界资源),二是存在多条线程共同操作共享数据。 因此为了解决这个问题,我们可能需要这样一...
  • huaxun66
  • huaxun66
  • 2017年09月12日 10:38
  • 481

Java主线程等待子线程、线程池

public class TestThread extends Thread { public void run() { System.out.println(this.getName() +...
  • xiao__gui
  • xiao__gui
  • 2013年07月01日 13:52
  • 23697
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:线程的等待唤醒机制
举报原因:
原因补充:

(最多只允许输入30个字)