`
sealbird
  • 浏览: 571304 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

老紫竹JAVA提高教程-信号量(Semaphore)在生产者和消费者模式的使用

    博客分类:
  • JAVA
阅读更多
Semaphore 信号量,就是一个允许实现设置好的令牌。也许有1个,也许有10个或更多。
谁拿到令牌(acquire)就可以去执行了,如果没有令牌则需要等待。
执行完毕,一定要归还(release)令牌,否则令牌会被很快用光,别的线程就无法获得令牌而执行下去了。

请仔细体会里面关于仓库的处理,

1 是如何保证入库时,如果仓库满就等待,

2 出库时,如果仓库无货就等待的。

3 以及对仓库只有10个库位的处理。

4 对同步问题的处理。

view plaincopy to clipboardprint?
01.import java.util.concurrent.Semaphore;   
02./**  
03. * 老紫竹JAVA提高教程-信号量(Semaphore)的使用。<br>  
04. * 生产者和消费者的例子,库存的管理。  
05. *   
06. * @author 老紫竹(java2000.net,laozizhu.com)  
07. */  
08.public class TestSemaphore {   
09.  public static void main(String[] args) {   
10.    // 启动线程   
11.    for (int i = 0; i <= 3; i++) {   
12.      // 生产者   
13.      new Thread(new Producer()).start();   
14.      // 消费者   
15.      new Thread(new Consumer()).start();   
16.    }   
17.  }   
18.  // 仓库   
19.  static Warehouse buffer = new Warehouse();   
20.  // 生产者,负责增加   
21.  static class Producer implements Runnable {   
22.    static int num = 1;   
23.    @Override  
24.    public void run() {   
25.      int n = num++;   
26.      while (true) {   
27.        try {   
28.          buffer.put(n);   
29.          System.out.println(">" + n);   
30.          // 速度较快。休息10毫秒   
31.          Thread.sleep(10);   
32.        } catch (InterruptedException e) {   
33.          e.printStackTrace();   
34.        }   
35.      }   
36.    }   
37.  }   
38.  // 消费者,负责减少   
39.  static class Consumer implements Runnable {   
40.    @Override  
41.    public void run() {   
42.      while (true) {   
43.        try {   
44.          System.out.println("<" + buffer.take());   
45.          // 速度较慢,休息1000毫秒   
46.          Thread.sleep(1000);   
47.        } catch (InterruptedException e) {   
48.          e.printStackTrace();   
49.        }   
50.      }   
51.    }   
52.  }   
53.  /**  
54.   * 仓库  
55.   *   
56.   * @author 老紫竹(laozizhu.com)  
57.   */  
58.  static class Warehouse {   
59.    // 非满锁   
60.    final Semaphore notFull = new Semaphore(10);   
61.    // 非空锁   
62.    final Semaphore notEmpty = new Semaphore(0);   
63.    // 核心锁   
64.    final Semaphore mutex = new Semaphore(1);   
65.    // 库存容量   
66.    final Object[] items = new Object[10];   
67.    int putptr, takeptr, count;   
68.    /**  
69.     * 把商品放入仓库.<br>  
70.     *   
71.     * @param x  
72.     * @throws InterruptedException  
73.     */  
74.    public void put(Object x) throws InterruptedException {   
75.      // 保证非满   
76.      notFull.acquire();   
77.      // 保证不冲突   
78.      mutex.acquire();   
79.      try {   
80.        // 增加库存   
81.        items[putptr] = x;   
82.        if (++putptr == items.length)   
83.          putptr = 0;   
84.        ++count;   
85.      } finally {   
86.        // 退出核心区   
87.        mutex.release();   
88.        // 增加非空信号量,允许获取商品   
89.        notEmpty.release();   
90.      }   
91.    }   
92.    /**  
93.     * 从仓库获取商品  
94.     *   
95.     * @return  
96.     * @throws InterruptedException  
97.     */  
98.    public Object take() throws InterruptedException {   
99.      // 保证非空   
100.      notEmpty.acquire();   
101.      // 核心区   
102.      mutex.acquire();   
103.      try {   
104.        // 减少库存   
105.        Object x = items[takeptr];   
106.        if (++takeptr == items.length)   
107.          takeptr = 0;   
108.        --count;   
109.        return x;   
110.      } finally {   
111.        // 退出核心区   
112.        mutex.release();   
113.        // 增加非满的信号量,允许加入商品   
114.        notFull.release();   
115.      }   
116.    }   
117.  }   
118.}  
import java.util.concurrent.Semaphore;
/**
 * 老紫竹JAVA提高教程-信号量(Semaphore)的使用。<br>
 * 生产者和消费者的例子,库存的管理。
 * 
 * @author 老紫竹(java2000.net,laozizhu.com)
 */
public class TestSemaphore {
  public static void main(String[] args) {
    // 启动线程
    for (int i = 0; i <= 3; i++) {
      // 生产者
      new Thread(new Producer()).start();
      // 消费者
      new Thread(new Consumer()).start();
    }
  }
  // 仓库
  static Warehouse buffer = new Warehouse();
  // 生产者,负责增加
  static class Producer implements Runnable {
    static int num = 1;
    @Override
    public void run() {
      int n = num++;
      while (true) {
        try {
          buffer.put(n);
          System.out.println(">" + n);
          // 速度较快。休息10毫秒
          Thread.sleep(10);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
  }
  // 消费者,负责减少
  static class Consumer implements Runnable {
    @Override
    public void run() {
      while (true) {
        try {
          System.out.println("<" + buffer.take());
          // 速度较慢,休息1000毫秒
          Thread.sleep(1000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
  }
  /**
   * 仓库
   * 
   * @author 老紫竹(laozizhu.com)
   */
  static class Warehouse {
    // 非满锁
    final Semaphore notFull = new Semaphore(10);
    // 非空锁
    final Semaphore notEmpty = new Semaphore(0);
    // 核心锁
    final Semaphore mutex = new Semaphore(1);
    // 库存容量
    final Object[] items = new Object[10];
    int putptr, takeptr, count;
    /**
     * 把商品放入仓库.<br>
     * 
     * @param x
     * @throws InterruptedException
     */
    public void put(Object x) throws InterruptedException {
      // 保证非满
      notFull.acquire();
      // 保证不冲突
      mutex.acquire();
      try {
        // 增加库存
        items[putptr] = x;
        if (++putptr == items.length)
          putptr = 0;
        ++count;
      } finally {
        // 退出核心区
        mutex.release();
        // 增加非空信号量,允许获取商品
        notEmpty.release();
      }
    }
    /**
     * 从仓库获取商品
     * 
     * @return
     * @throws InterruptedException
     */
    public Object take() throws InterruptedException {
      // 保证非空
      notEmpty.acquire();
      // 核心区
      mutex.acquire();
      try {
        // 减少库存
        Object x = items[takeptr];
        if (++takeptr == items.length)
          takeptr = 0;
        --count;
        return x;
      } finally {
        // 退出核心区
        mutex.release();
        // 增加非满的信号量,允许加入商品
        notFull.release();
      }
    }
  }
}

发表于 @ 2009年03月17日 11:11:00 | 评论( 4 ) | 编辑| 举报| 收藏

旧一篇:平庸和优秀的距离,我要得不仅仅是土豆 | 新一篇:国内顶级IT公司面试题的答案
查看最新精华文章 请访问博客首页相关文章
生产者消费者问题的java实现有趣的生产者消费者问题老紫竹JAVA提高教程(1)-认识Set集合老紫竹JAVA提高教程(7)-认识List列表之ArrayListQt 多线程学习(1)线程同步Condition Variables JAVA多线程生产者消费者问题——Java方案zhangweiheb 发表于2009年3月17日 22:06:26  IP:举报回复删除
今天上午的操作系统的课也讲到这里了,本来也想用Java写个例子试一下,看来赵老师先把样板写出来了,哈哈...
顺便问一下赵老师,Semaphore 和 synchronize 有什么联系吗?liu251 发表于2010年1月7日 18:49:25  IP:举报回复删除
在有些系统中没有互斥锁mutex原语,只有信号量,此时synchronized的实现是通过semaphore实现的yin_slin 发表于2010年7月23日 17:20:54  IP:举报回复删除
代码很精彩,写出了Semaphore的用途,特别是核心锁的互斥作用,但这段代码性能并不高,生产者和消费者是单线程运作的,没有体现concurrency包的高性能特性

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/java2000_net/archive/2009/03/17/3997449.aspx
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics