一个notify()的实例分析
2013-01-10 12:41
323 查看
在java多线程编程中,就要涉及到了对于资源的访问,当多个线程同时访问一个资源的时候就要涉及到一种访问策略。java提供了锁的机制,就是一个线程访问这个资源的时候可以先把这个资源锁住可以用synchronized(the object)来锁定the object,其他访问这个资源的线程就进入阻塞状态,直到当前的线程执行了这个对象的notify或者notifyall其他访问这个对象的阻塞状态的线程才有可能变成就绪状态。其中notify是唤醒一个线程,而notifyall是唤醒所有阻塞进程。
如下是一个这方面的实例
//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之后并不认为已经获取了对象,依然需要去和其他线程抢对象才能继续执行下去。
如下是一个这方面的实例
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之后并不认为已经获取了对象,依然需要去和其他线程抢对象才能继续执行下去。
相关文章推荐
- ANR的一个实例分析
- cxf webservice做一个简单的实例 错误分析(个人经验)
- 以一个wav文件为实例分析wav文件格式
- php和数据库结合的一个简单的web实例 代码分析 (php初学者)
- 通过一个对数据的存储和分析的简单实例初识Hadoop
- WM_NOTIFY消息流程实例分析
- 一个创业的实例分析(转载)
- linux驱动—input输入子系统—The simplest example(一个最简单的实例)分析(1)
- 一个侧屏滑动操作的实例(仿遇见)之三:代码分析
- 一个AJAX+Database+XML的实例分析.(ajaxImage)
- 一个简单实例的LR分析过程
- 一个普通的DataGrid模板实例与分析(原创)
- 谈谈对于ajax的理解和ajax一个实例分析。
- php定义一个参数带有默认值的函数实例分析
- php和数据库结合的一个简单的web实例 代码分析 (php初学者)
- 时间序列形态相似性分析(二)——相似性度量的一个应用实例
- 深入理解函数内部原理(2)——对一个函数实例进行深入的分析
- Linux设备驱动程序架构分析之一个I2C驱动实例
- linux kernel虚拟内存地址耗尽一个实例分析
- Java静态变量初始化的一个实例的分析