【问题标题】:Use semaphore to implement monitor使用信号量实现监控
【发布时间】:2017-04-03 16:01:19
【问题描述】:

我想用 Semaphore 来实现 Monitor。我创建了 2 个班级。缓冲区和线程演示。在 Buffer 类中,我创建了 put() 和 get() 方法(我从这个页面获取代码)

public void put(int input) throws InterruptedException {
    monitorSemaphore.acquire();
    boolean acquired = false;
    while (numberInBuffer == size) {
        // Equivalent of wait()
        if (acquired) {
            dec();
            notifyCalled.release();
        }
        inc();
        monitorSemaphore.release();
        notifyCalled.acquire();
        monitorSemaphore.acquire();
        acquired = true;
    }

    // Critical section
    buffer[last] = input;
    last = (last + 1) % size;
    numberInBuffer++;

    // Equivalent of notifyAll()
    for (int i = val(); i > 0; i--) {
        dec();
        notifyCalled.release();
    }

    monitorSemaphore.release();
}

public int get() throws InterruptedException {
    monitorSemaphore.acquire();

    boolean acquired = false;
    while (numberInBuffer == 0) {
        // Equivalent of wait()
        if (acquired) {
            dec();
            notifyCalled.release();
        }
        inc();
        monitorSemaphore.release();
        notifyCalled.acquire();
        monitorSemaphore.acquire();
        acquired = true;
    }

    // Critical section
    int temp = buffer[start];
    start = (start + 1) % size;
    numberInBuffer--;

    // Equivalent of notifyA(ll)
    for (int i = val(); i > 0; i--) {
        dec();
        notifyCalled.release();
    }

    monitorSemaphore.release(); 

    return temp;
}

在TestThread 类中,我创建了Thread-T1、Thread-T2。但我不能在 Buffer 类中调用 put 和 Get。

public class TestThread extends Thread {
private Thread t;
   private String threadName;

   public TestThread(String name) {
       threadName = name;
       System.out.println("Creating " +  threadName );
   }

   public void run() {
      System.out.println("Running " +  threadName );
      try {
            put(2);//I can't call this method
            Thread.sleep(5000);
            get(); //
            Thread.sleep(5000);
         } catch (InterruptedException e) {
         System.out.println("Thread " +  threadName + " interrupted.");
     }
     System.out.println("Thread " +  threadName + " exiting.");
   }


   public void start ()
   {
      System.out.println("Starting " +  threadName );
      if (t == null)
      {
         t = new Thread (this, threadName);
         t.start ();
      }
   }


public static void main(String[] args) {

      TestThread T1 = new TestThread( "Thread-1");
      T1.start();

      TestThread T2 = new TestThread( "Thread-2");
      T2.start();

}}

如果我在 TestThread 类中的代码不正确,请告诉我。谢谢!

【问题讨论】:

    标签: java concurrency semaphore monitor


    【解决方案1】:

    我认为...假设您在 Buffer 类中定义了 get() 和 put() 方法。然后你应该在调用类内方法之前先初始化类实例。就像下面的代码:

    public class TestThread extends Thread {
       private Thread t;
       private String threadName;
       private Buffer buffer;
    
       public TestThread(String name, Buffer buffer) {
           threadName = name;
           this.buffer = buffer;
           System.out.println("Creating " +  threadName );
       }
    
       public void run() {
          System.out.println("Running " +  threadName );
          try {
                buffer.put(2);//I can't call this method
                Thread.sleep(5000);
                buffer.get(); //
                Thread.sleep(5000);
             } catch (InterruptedException e) {
             System.out.println("Thread " +  threadName + " interrupted.");
         }
         System.out.println("Thread " +  threadName + " exiting.");
       }
    }
    

    【讨论】:

    • 如何创建对象TestThread? TestThread T1 = new TestThread("Thread-1", ???);
    • “???”应该是您的 Buffer 对象。这意味着您需要在初始化线程之前创建一个缓冲区对象。此后不同的线程可以将同一个缓冲区对象作为构造函数的输入,然后对同一个缓冲区对象进行并发操作。
    • 没问题。祝你的学习之旅好运!另外,觉得有帮助的可以采纳我的回答:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 2011-08-25
    • 2016-08-19
    • 1970-01-01
    • 2013-11-30
    相关资源
    最近更新 更多