二进制信号量和缓冲区按顺序打印

时间:2015-05-08 01:33:18

标签: java

我试图打印一组字符。

字符1和2必须按顺序排列如下:1212121212。​​字符3间歇打印,但不得超过字符2.

我已经完成了任务的第一部分(1和2),但是在介绍3时我很挣扎。我知道我需要使用计数信号量来破解它。

这是针对学校的,所以请你能避免粘贴任何代码并给我一些指示吗?我只是展示了两个类:我的缓冲区和打印字符的线程。

感谢。

public class PrintLetterA extends Thread {

   private char letter;
   private Buffer buffer;

   public PrintLetterA(char letter, Buffer b) {
      this.letter = letter;
      buffer = b;
   }

   public void run() {

      while (true) {
         if (letter == 'F') {
             Object a = new Object();
             buffer.put(a);
             System.out.println("" + letter);
             try {
                 Thread.sleep( (int) Math.random() * 100);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
        } else if (letter == 'G'){
             Object a = buffer.get();
             System.out.println("" + letter);           
             try {
                Thread.sleep( (int) Math.random() * 100);
             }  catch (InterruptedException e) {
                e.printStackTrace();
             }
public class Buffer {

    private Object message = null;

    BinarySemaphore Fbinary = new BinarySemaphore(1);
    BinarySemaphore Gbinary = new BinarySemaphore(0);


    public synchronized  void put(Object message) {
          try {
               Fbinary.P();
          } catch (InterruptedException e) {
              e.printStackTrace();
          }

          this.message = message;
          Gbinary.V();
   }

  public synchronized Object get() { 
       try {
         Gbinary.P();
       } catch (InterruptedException e) {
         e.printStackTrace();
       }

       Object m = message;
       Fbinary.V();
       return m;
  }

1 个答案:

答案 0 :(得分:0)

首先,考虑为你的线程创建两个不同的类(可能还有一个常见的抽象超类)而不是run()中的if/else fork。

现在,看看Semaphore class,请务必阅读该页面开头的说明,了解这个概念真的很有帮助。基本上,您关注的方法有两种:acquirerelease。每次打印“2”时,都会调用release方法。这增加了信号量持有的“许可”数量。现在,在另一个线程中,在打印“3”之前,你将调用acquire,它会检查是否有可用的许可证,如果没有,它将阻塞并等待,否则,它将减少数字和返回,以便您可以打印“3”。 当你以这种方式使用它时,信号量在任何给定时刻持有的许可数量将反映到目前为止打印的“2”多于“3”。永远不会有超过2的3s,因为acquire将不允许允许的数量为负数,如果它恰好是0,它将强制你的线程等到另一个打印另一个“2”并调用“释放”。