wait和notify的使用

当我们在编写多线程的代码的时候,经常会考虑到多线程对共享资源的竞争问题。其中扮演着重要角色的就是Objcet的方法:wait、wait(long waitTime)、notify、notifyAll。开始学习多线程的时候,一直以为是当前线程调用这几个方法,结果老是报IllegalMonitorStateException异常,后查阅资料后发现是没有加锁的问题导致的,再仔细研究后发现,应该是调用竞争资源的相关方法,由竞争资源来等待和通知。下边简要说明下这几个方法的含义:

 

 

wait:当一个锁对象执行wait的时候,必须要取的这个锁对象的控制权,一般是放到synchronized(lock)代码中

wait(2000):当前线程每等待2秒的时候,就去检测是否可以获取到竞争资源的控制权,一旦取到竞争资源的控制权,当前线程就可以继续执行,负责继续等待。

notify:通知等待当前竞争资源的一个线程,如果有多个线程等待该资源,只会通知等待队列中的第一个相关线程(不会通知优先级比较高的线程)

notifyALl:通知所有等待该竞争资源的线程(也不会按照线程的优先级来执行)

 

在编写代码的时候,当我们需要调用以上的方法的时候,一定要对竞争资源进行加锁,如果不加锁的话,则会报 IllegalMonitorStateException 异常。下边是测试代码:

 

 一、代码

package com.test.thread;

 

/**

 * 测试线程的wait和notify方法

 * 

 * @author rey

 * 

 */

public class TestThreadWait {

 

// 共享资源

private String[] lockObj = { "true" };

 

/**

* @param args

*/

public static void main(String[] args) {

TestThreadWait testMainThread = new TestThreadWait();

 

// 定义线程

NotifyThread notifyThread = testMainThread.new NotifyThread(

"notifyThread");

WatiThread wait01 = testMainThread.new WatiThread("wait01");

wait01.setPriority(2);

WatiThread wait02 = testMainThread.new WatiThread("wait02");

wait02.setPriority(3);

WatiThread wait03 = testMainThread.new WatiThread("wait03");

wait03.setPriority(4);

 

// 启动线程

notifyThread.start();

wait01.start();

wait02.start();

wait03.start();

 

}

 

// 定义通知线程

class NotifyThread extends Thread {

public NotifyThread(String _sThreadName) {

super(_sThreadName);

}

 

public void run() {

 

// 休眠5秒,给等待线程等待时间

try {

sleep(5000);

} catch (InterruptedException e) {

e.printStackTrace();

}

 

synchronized (lockObj) {

System.out.println("线程[" + getName() + "]开始准备通知.....");

lockObj[0] = "false";

lockObj.notifyAll();  //该成lockObj.notify();则运行测试的时候进程没有结束,因为我们还有2个线程没有结束

System.out.println("线程[" + getName() + "]开始通知结束.....");

}

 

System.out.println("线程[" + getName() + "]运行结束.....");

 

}

 

}

 

// 定义等待的线程类

class WatiThread extends Thread {

public WatiThread(String _sThreadName) {

super(_sThreadName);

}

 

public void run() {

 

synchronized (lockObj) {

while (lockObj[0].equalsIgnoreCase("true")) {

System.out.println("线程[" + this.getName() + "]开始等待....");

 

long lWaitTime = System.currentTimeMillis();

 

try {

lockObj.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

 

lWaitTime = System.currentTimeMillis() - lWaitTime;

System.out.println("线程[" + getName() + "]等待时间为:::"

+ lWaitTime);

}

}

 

System.out.println("线程[" + getName() + "]等待结束!!!");

}

}

 

}

 

二、运行测试用例后的一种可能结果(线程关闭的顺序可能不同,没有深入研究)

线程[wait01]开始等待....
线程[wait02]开始等待....
线程[wait03]开始等待....
线程[notifyThread]开始准备通知.....
线程[notifyThread]开始通知结束.....
线程[notifyThread]运行结束.....
线程[wait01]等待时间为:::5000
线程[wait01]等待结束!!!
线程[wait02]等待时间为:::5000
线程[wait02]等待结束!!!
线程[wait03]等待时间为:::5000
线程[wait03]等待结束!!!

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

O溺水的鱼0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值