java队列 notify_java使用wait(),notify(),notifyAll()实现等待/通知机制

public class WaitNotify {

static boolean flag=true;

static Object lock=new Object();

static class Wait implements Runnable{

@Override

public void run() {

synchronized (lock){

while(flag){

try{

System.out.println(Thread.currentThread()+" flag is true. wait " +

"@ "+new SimpleDateFormat("HH:mm:ss").format(new Date()));

lock.wait();

}catch (InterruptedException e){

}

}

}

System.out.println(Thread.currentThread()+" flag is false.running " +

"@"+new SimpleDateFormat("HH:mm:ss").format(new Date()));

}

}

static class Notify implements Runnable{

@Override

public void run() {

synchronized (lock) {

System.out.println(Thread.currentThread() + " hold lock. notify " +

"@ " + new SimpleDateFormat("HH:mm:ss").format(new Date()));

lock.notifyAll();

flag = false;

SleepUtils.second(5);

}

synchronized (lock){

System.out.println(String.format(Thread.currentThread() + " hold lock again. sleep " +

"@" + new SimpleDateFormat("HH:mm:ss").format(new Date())));

SleepUtils.second(5);

}

}

}

public static void main(String[] args) {

Thread waitThread=new Thread(new Wait(),"WaitThread");

waitThread.start();

try {

TimeUnit.SECONDS.sleep(1);

}catch (InterruptedException e){

}

Thread notifyThread=new Thread(new Notify(),"NotifyThread");

notifyThread.start();

}

}

程序执行结果:

Thread[WaitThread,5,main] flag is true. wait @ 14:41:12

Thread[NotifyThread,5,main] hold lock. notify @ 14:41:13

Thread[NotifyThread,5,main] hold lock again. sleep @14:41:18

Thread[WaitThread,5,main] flag is false.running @14:41:23

1.使用wait(),notify(),notifyAll()方法之前,要获取同一个对象的锁。

2.调用wait()方法之后,线程会从RUNABLE状态变为WAITING状态,并会释放对象锁,并会将线程移入到对象的等待队列中。

3.notify()和notifyAll()调用之后,等待的线程的wait方法并不会立马返回,需要锁空闲的时候,等待的线程获取了锁,wait()方法才会返回。

4.调用了notify()和notifyAll()方法之后,notify会将一个线程从等待队列放置到同步队列,同步队列是因为锁被占有而处于BLOCKED阶段的线程,notifyAll则是将等待队列中所有的线程都移动到同步队列,这两个方法都是将线程从WAITING状态变为BLOCKED状态。

5.从wait方法返回的条件是获得了调用对象的锁。

该程序的执行流程是首先WaitThread获取了lock,然后waitThread调用wait方法,会释放锁,并将锁移入等待队列,接着notifyThread会获取锁,调用notifyAll,但是wait()方法并没有返回,因为lock没有释放,notifyThread会睡眠5秒,这时同步队列中有两个线程要获取lock,一个是notifyThread,一个是WaitThread,结果显示是notifyThread又重新获取了锁,所以这时的wait方法依然不能返回,当notifyThread执行完了之后,释放锁,waitThread获取了锁,并且wait方法返回,waitThread执行完成。

java等待/通知经典模式

等待方:

1)获取对象锁

2)如果条件不满足,那么就调用对象的wait()方法,被通知后依然要检查条件

3)条件满足则执行相应逻辑

对应的伪代码:

synchronized(对象){

while(条件不满足){

对象.wait()

}

执行对应逻辑代码

}

通知方:

1)获取对象锁

2)改变条件

3)通知所有在该对象上等待的线程

对应的伪代码:

synchronized(对象){

改变对象条件

对象.notifyAll()

}

java中的Thread.join()方法使用了等待/通知经典范式

java中的Thread.join()也算是线程通信的一种方式,表示挂起当前线程,执行子线程,等到子线程执行完成之后再返回。join()方法还提供了两个超时方法,如果子线程在规定时间没有终止,就会从join()方法中返回。

Thread.join()方法源代码:

//join函数的超时方法

public final synchronized void join(long millis)

throws InterruptedException {

long base = System.currentTimeMillis();

long now = 0;

//如果设置的超时时间小于0,抛出异常

if (millis < 0) {

throw new IllegalArgumentException("timeout value is negative");

}

//调用wait()的时候采用delay

if (millis == 0) {

while (isAlive()) {

wait(0);

}

} else {

while (isAlive()) {

long delay = millis - now;

if (delay <= 0) {

break;

}

wait(delay);

now = System.currentTimeMillis() - base;

}

}

}

public final synchronized void join(long millis, int nanos)

throws InterruptedException {

if (millis < 0) {

throw new IllegalArgumentException("timeout value is negative");

}

if (nanos < 0 || nanos > 999999) {

throw new IllegalArgumentException(

"nanosecond timeout value out of range");

}

if (nanos >= 500000 || (nanos != 0 && millis == 0)) {

millis++;

}

join(millis);

}

public final void join() throws InterruptedException {

join(0);

}

子线程执行完成之后会调用子线程的notifyAll(),会通知所有等待在该线程对象上的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值