您的位置:首页 > 其它

一个notify()的实例分析

2013-01-10 12:41 323 查看
在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之后并不认为已经获取了对象,依然需要去和其他线程抢对象才能继续执行下去。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: