一个notify()的实例分析

在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之后并不认为已经获取了对象,依然需要去和其他线程抢对象才能继续执行下去。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值