public synchronized void set(char c) { if (condition) this.wait(); } 比如两个线程序A1,A2, 1. A1先进入方法set,被挂起(this.wait()),同时释放对这个方法的锁. 2. A2随后也进入, a. 如果它不先notify(),自己又被wait(),那两个线程都被挂起. b. 如果notify后wait,那A1可以继续执行,A1在自己被挂起前又notify唤醒A2.这样两个线程可以轮流执行.不会出现两个线程都被挂起的现象. 说白了,就是不能让抢资源的线程都挂起,那整个程序就永远死在那儿了.
to cenlmmx: 你没有说明为什么要同步,另外,被notify后,不一定是a1先执行啊,是从a1,a2随机挑选一个执行的。同步的含义只是某一时刻,该对象被某个线程独占访问,我看不出这和wait有什么联系,因为需要wait是由前面的判断条件决定的,在需要的时候wait。to tlowl: 我玩文字游戏了吗?
to hax: 文档上写的是,wait暂时挂起,直到调用了notify才继续执行后面的语句,我不明白,为什么挂起就需要在同步里才能挂起,按你说的释放当前的锁,那么为什么一定要先加锁呢
既然你看文档,为什么还没有读明白呢?看看我用*标注的部分。public final void wait() throws InterruptedExceptionCauses 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). 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. As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop: 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. See the notify method for a description of the ways in which a thread can become the owner of a monitor. public final void 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. 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. By executing the body of a synchronized statement that synchronizes on the object. For objects of type Class, by executing a synchronized static method of that class. Only one thread at a time can own an object's monitor. 注:monitor就是lock的意思。
同步只是给对象加锁,和wait有什么关系呢
{
if (condition)
this.wait();
}
比如两个线程序A1,A2,
1. A1先进入方法set,被挂起(this.wait()),同时释放对这个方法的锁.
2. A2随后也进入,
a. 如果它不先notify(),自己又被wait(),那两个线程都被挂起.
b. 如果notify后wait,那A1可以继续执行,A1在自己被挂起前又notify唤醒A2.这样两个线程可以轮流执行.不会出现两个线程都被挂起的现象.
说白了,就是不能让抢资源的线程都挂起,那整个程序就永远死在那儿了.
你没有说明为什么要同步,另外,被notify后,不一定是a1先执行啊,是从a1,a2随机挑选一个执行的。同步的含义只是某一时刻,该对象被某个线程独占访问,我看不出这和wait有什么联系,因为需要wait是由前面的判断条件决定的,在需要的时候wait。to tlowl:
我玩文字游戏了吗?
运行
阻塞
等待wait()方法的意思很明确,就是把线程加入等待队列,(原因很多,比如,等待一个资源)
notify()方法就是把线程从等待队列放到就绪队列!
所以呢?为什么需要同步。
文档上写的是,wait暂时挂起,直到调用了notify才继续执行后面的语句,我不明白,为什么挂起就需要在同步里才能挂起,按你说的释放当前的锁,那么为什么一定要先加锁呢
throws InterruptedExceptionCauses 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). 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. As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop: 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. See the notify method for a description of the ways in which a thread can become the owner of a monitor.
public final void 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. 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.
By executing the body of a synchronized statement that synchronizes on the object.
For objects of type Class, by executing a synchronized static method of that class.
Only one thread at a time can own an object's monitor.
注:monitor就是lock的意思。