Object Thead方法

Object

wait()

Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).

调用wait()方法会导致当前线程等待,直到另一个线程调用此对象的notify()方法或notifyAll()方法。换句话说,这个方法的行为与它简单地执行调用wait(0)完全一样。

The current thread must own this object’s monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object’s monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

当前线程必须拥有此对象的锁。线程释放此锁的所有权,并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待该对象的锁的线程们唤醒。然后,线程等待,直到它可以重新获得锁的所有权,并继续执行。

As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:

在一个参数版本中,中断和虚假的唤醒是可能的,这个方法应该总是在循环中使用:

1
2
3
4
5
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}

This method should only be called by a thread that is the owner of this object’s monitor.

此方法应仅由此对象锁的所有者所在的线程调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 在调用wait方法时,线程必须要持有被调用对象的锁,当调用wait方法后,线程就会释放掉该对象的锁。
* 在调用Thread类的sleep方法时,线程是不会释放掉对象的锁的
*/
public class MyTest1 {
public static void main(String[] args) throws InterruptedException {
Object object = new Object();
synchronized (object) {
object.wait();
}
}
}

wait(long timeout)

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

导致当前线程等待,直到另一个线程调用此对象的notify()方法或notifyAll()方法,或者经过指定的时间量。

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.

此方法导致当前线程(称为T)将自己放入此对象的等待集合中,然后放弃此对象上的所有同步声明(即释放锁)。

Thread T becomes disabled for thread scheduling purposes and lies dormant until one of four things happens:

线程T在线程调度时被禁用,并处于休眠状态,直到发生以下四种情况之一:

  • 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.

  • 其他一些线程调用此对象的notify方法,而线程T恰好被任意选择为要唤醒的线程。

  • 其他一些线程调用此对象的notifyAll方法。
  • 其他一些线程中断线程T。
  • 指定的实时时间已经过了,或多或少。但是,如果超时为零,则不考虑实时,线程只是等待,直到得到通知。

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.

然后从该对象的等待集中删除线程T,并重新启用线程调度。然后它以通常的方式与其他线程竞争对象上的同步权;一旦它获得了对对象的控制,它对对象的所有同步声明就会恢复到原来的状态——也就是说,恢复到调用wait方法时的状态。然后线程T从wait方法的调用返回。因此,从wait方法返回时,对象和线程T的同步状态与调用wait方法时的同步状态完全相同。

A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops, like this one:

线程也可以在没有通知、中断或超时的情况下唤醒,这就是所谓的伪唤醒。虽然这种情况在实践中很少发生,但是应用程序必须通过测试导致线程被唤醒的条件来防范这种情况,如果条件不满足,则继续等待。换句话说,等待应该总是在循环中发生,就像这个:

1
2
3
4
5
synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout);
... // Perform action appropriate to condition
}

If the current thread is interrupted by any thread before or while it is waiting, then an InterruptedException is thrown. This exception is not thrown until the lock status of this object has been restored as described above.

如果当前线程在等待之前或等待期间被任何线程中断,则抛出InterruptedException。在此对象的锁状态如前所述恢复之前,不会引发此异常。

Note that the wait method, as it places the current thread into the wait set for this object, unlocks only this object; any other objects on which the current thread may be synchronized remain locked while the thread waits.

注意,wait方法在将当前线程放入该对象的等待集中时,只解锁该对象;当前线程可能被同步的任何其他对象在线程等待期间保持锁定状态。

This method should only be called by a thread that is the owner of this object’s monitor. S

此方法应仅由此对象锁的所有者所在的线程调用。

notify

Wakes up a single thread that is waiting on this object’s monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object’s monitor by calling one of the wait methods.

唤醒正在等待此对象锁的单个线程。如果有多个线程正在等待这个对象的锁,则选择其中一个线程被唤醒。这个选择是任意的,由实现来决定。线程通过调用一个wait方法来等待对象的锁。

The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object. The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.

被唤醒的线程将无法继续,直到当前线程释放该对象上的锁。被唤醒的线程将以通常的方式与任何其他线程竞争,这些线程可能正在积极地对这个对象进行同步;例如,在成为下一个锁定该对象的线程时,被唤醒的线程没有任何可靠的特权或缺点。

This method should only be called by a thread that is the owner of this object’s monitor. A thread becomes the owner of the object’s monitor in one of three ways:

此方法应仅由此对象锁的所有者所在的线程调用。线程通过以下三种方式之一成为对象锁的所有者:

By executing a synchronized instance method of that object.

通过执行该对象的synchronized实例方法。

By executing the body of a synchronized statement that synchronizes on the object.

通过执行对对象进行同步的synchronized语句块。

For objects of type Class, by executing a synchronized static method of that class.

对于Class类型的对象,通过执行该类的同步静态方法。

Only one thread at a time can own an object’s monitor.

一次只有一个线程可以拥有一个对象的锁。

notifyAll

Wakes up all threads that are waiting on this object’s monitor. A thread waits on an object’s monitor by calling one of the wait methods.

唤醒正在此对象上等待的所有线程。线程通过调用一个wait方法来等待对象的锁。

The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object. The awakened threads will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened threads enjoy no reliable privilege or disadvantage in being the next thread to lock this object.

被唤醒的线程将无法继续,直到当前线程释放该对象上的锁。被唤醒的线程将以通常的方式与任何其他线程竞争,这些线程可能正在积极地对这个对象进行同步;例如,在成为下一个锁定此对象的线程时,被唤醒的线程没有任何可靠的特权或缺点。

This method should only be called by a thread that is the owner of this object’s monitor.

此方法应仅由此对象锁的所有者所在的线程调用。

Thread

sleep()

Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.

根据系统计时器和调度器的精度和准确性,使当前执行的线程休眠(临时停止执行)指定的毫秒数。线程不会失去任何锁的所有权。

总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 在调用wait方法时,线程必须要持有被调用对象的锁,当调用wait方法后,线程就会释放掉该对象的锁。
* 在调用Thread类的sleep方法时,线程是不会释放掉对象的锁的。
*
* 1. 当调用wait时,首先需要确保调用了wait方法的线程已经持有了对象的锁。
* 2. 当调用了wait后,该线程就会释放掉这个对象的锁,然后进入等待状态(wait set)。
* 3. 当线程调用了wait后进入到等待状态时,它就可以等待其他线程调用相同对象的notify或notifyAll方法来是的自己被唤醒。
* 4. 一旦这个线程被其他线程唤醒后,该线程就会与其他线程一同开始竞争这个对象的锁(公平竞争);只有当该线程获取到了这个对象的锁后,线程才会继续往下执行。
* 5. 调用wait方法的代码片段需要放在一个synchronized块或者是synchronized方法中,这样才可以确保线程在调用wait方法前已经获取到了对象的锁。
* 6. 当调用对象的notify方法时,它会随机唤醒该对象等待集合(wait set)中的任意一个线程,当某个线程被唤醒后,它就会与其他线程一同竞争对象的锁。
* 7. 当调用对象的notifyAll方法时,它会唤醒该对象等待集合(wait set)中的所有线程,这些线程被唤醒后,又会开始竞争对象的锁。
* 8. 在某一时刻,只有唯一一个线程可以拥有对象的锁。
*/
public class MyTest1 {
public static void main(String[] args) throws InterruptedException {
Object object = new Object();
synchronized (object) {
object.wait();
}
}
}