`
sealbird
  • 浏览: 575336 次
  • 性别: 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
分享到:
评论

相关推荐

    JAVA多线程--信号量(Semaphore)_.docx

    在Java中,还可以设置该信号量是否采纳公正模式,假如以公正方式执行,则线程将会按到达的挨次(FIFO)执行,假如是非公正,则可以后恳求的有可能排在队列的头部。 JDK中定义如下: ``` Semaphore(int permits, ...

    用多线程同步方法解决生产者-消费者问题(操作系统课设

    2. 信号量的实现:我们使用信号量来控制生产者和消费者的访问顺序。 3. 生产者线程的实现:我们实现了生产者线程的逻辑,包括生产数据和释放缓冲区的空闲信号量。 4. 消费者线程的实现:我们实现了消费者线程的逻辑...

    使用信号量(Semaphore)实现线程的同步

    使用信号量(Semaphore)实现线程的同步

    多线程代码 经典线程同步互斥问题 生产者消费者问题

    a: 创建一个线程 b: 创建多个线程 c: 多线程访问同一资源 d: 经典线程同步互斥问题 e: 使用关键段解决子线程互斥问题 f: 利用事件实现线程同步问题 ...I: 信号量 semaphore 解决线程同步问题

    java并发之Semaphore信号量.md

    Semaphore是计数信号量。Semaphore管理一系列许可证。每个acquire方法阻塞,直到有一个许可证可以获得然后拿走一个许可证;每个release方法增加一个许可证,这可能会释放一个阻塞的acquire方法。然而,其实并没有...

    C语言信号量同步与互斥生产者消费者互斥锁读写者问题哲学家就餐问题课程设计

    为了避免生产者和消费者之间的冲突,我们可以使用信号量机制来实现同步。 在本课程设计中,我们使用两个信号量 empty 和 full 来实现生产者消费者问题。empty 信号量用于记录空闲缓冲区的数量,full 信号量用于记录...

    Laravel开发-laravel-semaphore

    Laravel开发-laravel-semaphore 信号量集成到Laravel的通知层。

    Linux下多线程编程-Pthread与Semaphore的使用.doc

    Semaphore 可以用来解决多线程编程中的典型问题,如生产者-消费者问题。Semaphore 的使用可以分为两步:首先,创建一个 Semaphore 对象,然后使用 Semaphore 对象来控制线程的访问顺序。 在 Linux 下,我们可以使用...

    Swift-dispatch-semaphore

    Swift-dispatch_semaphore

    OC-dispatch-semaphore

    OC-dispatch_semaphore

    操作系统课程设计生产者和消费者问题源代码

    在测试用例文件中指定了所有的生产和消费的需求,只有当共享缓冲区的数据满足了所有关于它的消费需求后,此共享缓冲区才可以作为空闲空间允许新的生产者使用。 本实验在为生产者分配缓冲区时各生产者间必须互斥,...

    python实现生产者消费者并发模型

    多线程实现生产者消费者模型:锁(Lock)、信号量(Semaphore、BoundedSemaphore)、条件(Condition)、队列(Queue)、事件(Event) 多进程程实现生产者消费者模型:信号量(Semaphore)、条件(Condition)、...

    async-semaphore:基于Java并发信号量的计数信号量

    基于 Java 的并发信号量的计数信号量。 安装 通过 npm 安装模块: npm install async-semaphore 快速示例 // fairness false var Semaphore = require ( 'async-semaphore' ) ; var semaphore = new Semaphore ( ...

    生产者消费者问题操作系统课程设计思路.ppt

    生产者消费者问题可以通过使用信号量和管程来解决。生产者在生产数据时,首先申请信号量,然后将数据存储在缓冲区中。消费者在消费数据时,首先申请信号量,然后从缓冲区中取出数据。如果缓冲区为空,则消费者等待...

    C语言编程模拟生产者和消费者问题附代码程序.doc

    为了避免生产者将产品放入已满的缓冲器或者消费者从空缓冲器中取出产品,可以使用PV操作来实现生产者和消费者之间的同步。 在模拟实现中,缓冲器可以存放10件产品,生产者和消费者两个进程的程序如下所示: ```c B...

    生产者和消费者问题程序

    在测试用例文件中指定了所有的生产和消费的需求,只有当共享缓冲区的数据满足了所有关于它的消费需求后,此共享缓冲区才可以作为空闲空间允许新的生产者使用。 本实验在为生产者分配缓冲区时各生产者间必须互斥,...

    开源项目-vasilmkd-semaphore.zip

    开源项目-vasilmkd-semaphore.zip,A lockless semaphore package using atomic instructions, feedback appreciated

    信号量(Semaphore)

    信号量(Semaphore)哲学家进餐问题(the dining philosophers problem)---------------------------程序

    操作系统生产者和消费者问题.doc

    6. 使用信号量可以解决生产者-消费者问题,防止生产者和消费者线程同时操作缓冲区列表。 7. 互斥信号量用于阻止生产者线程和消费者线程同时操作缓冲区列表。 8. 信号量用于同步生产者线程和消费者线程的操作。

Global site tag (gtag.js) - Google Analytics