【Java基础】永远不会”唤醒”的 wait(long timeout)方法

void java.lang. Object.wait( long timeout) throws InterruptedException

Causes the current thread to wait until either another thread invokes the java.lang.Object.notify() method or the java.lang.Object.notifyAll() method for this object, or a specified amount of time has elapsed.

The current thread must own this object's monitor.

This method causes the current thread (call it T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object. Thread T becomes disabled for thread scheduling purposes and lies dormant until one of four things happens:

  • Some other thread invokes the notify method for this object and thread T happens to be arbitrarily chosen as the thread to be awakened.
  • Some other thread invokes the notifyAll method for this object.
  • Some other thread interrupts thread T.
  • The specified amount of real time has elapsed, more or less. If timeout is zero, however, then real time is not taken into consideration and the thread simply waits until notified.
The thread T is then removed from the wait set for this object and re-enabled for thread scheduling. It then competes in the usual manner with other threads for the right to synchronize on the object; once it has gained control of the object, all its synchronization claims on the object are restored to the status quo ante - that is, to the situation as of the time that the wait method was invoked. Thread T then returns from the invocation of the wait method. Thus, on return from the wait method, the synchronization state of the object and of thread T is exactly as it was when the wait method was invoked.


描述:

     1、调用该方法,导致当前线程(用T表示)阻塞,进入等待状态。

          当前线程T会把自己放入 等待集合 中(等待 obj.wait()的obj对象)。

    2、当前线程(T)程释放已获取obj的锁(别的线程可以获取了,如果有)。

    3、什么时候唤醒(从wait set 删除)?以下4种事件任何一个发生,即会唤醒。

        a, 其它的线程调用 obj.notify(),且当前线程T,正好是被选中唤醒的。

        b, 其它的线程调用 obj.notifyAll()。

        c.其它线程中断T。

       d.指定的等待时间(timeout)超时,(时间精度会有些误差)。

   4、当前线程T被唤醒后,它被移出等待集合,重新被调度。

         它需要和其它线程平等的(没有任何特权)竞争,获取obj的锁。


本文标题,永远不会唤醒,其实不是不会唤醒,而是唤醒后,可能获取不到锁。

代码示例:

package com.wateray.java.thread;

public class WaitTimeDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Object obj = new Object();

		Thread thA = new Thread(new Task2(obj));
		thA.setName("thread A");
		thA.start();

		// thB run forever!
		Thread thB = new Thread(new Task3(obj));
		thB.setName("thread B");
		thB.start();
	}

}

class Task2 implements Runnable {
	private Object obj;

	public Task2(Object obj) {
		this.obj = obj;
	}

	@Override
	public void run() {

		while (true) {
			synchronized (obj) {
				try {
					System.out.format("%s waiting...%n%n", Thread
							.currentThread().getName());

					// 等待1秒,wait会释放锁
					obj.wait(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.format("%s awaked!%n%n", Thread.currentThread()
					.getName());
		}
	}
}

class Task3 implements Runnable {
	private Object obj;

	public Task3(Object obj) {
		this.obj = obj;
	}

	@Override
	public void run() {
		long start = System.currentTimeMillis();

		synchronized (obj) {
			// 获取锁后,永不释放
			while (true) {
				try {
					// 每5秒打印一次
					if ((System.currentTimeMillis() - start) % 5000 == 0) {
						System.out.format("%s ...%n%n", Thread.currentThread()
								.getName());
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值