在java多线程编程中,就要涉及到了对于资源的访问,当多个线程同时访问一个资源的时候就要涉及到一种访问策略。java提供了锁的机制,就是一个线程访问这个资源的时候可以先把这个资源锁住可以用synchronized(the object)来锁定the object,其他访问这个资源的线程就进入阻塞状态,直到当前的线程执行了这个对象的notify或者notifyall其他访问这个对象的阻塞状态的线程才有可能变成就绪状态。其中notify是唤醒一个线程,而notifyall是唤醒所有阻塞进程。
如下是一个这方面的实例
package concurrent;
import java.util.concurrent.TimeUnit;
/**
* Wait、Notify、NotifyAll的区别
* @author yydcj
* Email:yydcj@163.com
* 网址:<a>http://yydcj.iteye.com</a>
*/
public class WaitNotify {
private static int reduceThreadCount =0;
/**
* @param args
*/
public static void main(String[] args) {
WaitNotify notify = new WaitNotify();
Source source = notify.new Source("source");
for (int i = 0; i < 10; i++)
notify.new ReduceThread(source).start();
// try {
// TimeUnit.SECONDS.sleep(5);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
notify.new AddThread(source).start();
}
class ReduceThread extends Thread{
private Source source;
public ReduceThread(Source source){
super("ReduceThread-" + reduceThreadCount++);
this.source = source;
}
public void run(){
for (int i = 0; i < 10; i++){
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
source.reduceCount();
}
}
}
class AddThread extends Thread{
private Source source;
public AddThread(Source source){
super("AddThread");
this.source = source;
}
public void run(){
for (int i = 0; i < 1; i++){
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
source.addCount();
}
}
}
class Source{
private int count = 0;
public Source(String name){
// this.name = name;
}
public synchronized void addCount() {
System.out.println(Thread.currentThread().getName()+": count+1="+ ++count);
notify();
}
public synchronized void reduceCount() {
while (count <= 0) {
try {
System.out.println(Thread.currentThread().getName()+" wait()");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+": count-1="+ --count);
}
}
}
//output:
ReduceThread-1 wait()
ReduceThread-5 wait()
ReduceThread-8 wait()
ReduceThread-6 wait()
ReduceThread-4 wait()
ReduceThread-2 wait()
ReduceThread-0 wait()
AddThread: count+1=1
ReduceThread-7: count-1=0
ReduceThread-9 wait()
ReduceThread-3 wait()
ReduceThread-1 wait()
ReduceThread-7 wait()
我这里是用notify()来唤醒其中一个ReduceThread线程的(此时notify的是ReduceThread-7),然后ReduceThread-7执行完消费任务后又进入了wait()、10个reduce线程虽然是顺序实例化的,但是他们并不是顺序拿到souce对象的。依次拿到souce对象的1586420 这7个线程,各个线程因为count 为0释放了这个对象给其他的线程。然后AddThread拿到了这个对象,将count变为1,notify了一个线程,这个线程就是1。虽然1被notify了,但是他并没有取得对象,对象被7获取了并将count设置为0,所以等于说1这个线程醒来之后发现count依然为0,所以又wait了一遍
一个线程被notify之后并不认为已经获取了对象,依然需要去和其他线程抢对象才能继续执行下去。