如何通过信号量替换synchronized,wait,notify? (生产者 - 消费者)

时间:2014-12-03 20:55:54

标签: java wait semaphore synchronized notify

晚上好,

我想知道如何用信号量替换以下代码中的synchronized,wait和notify?我在哪里创建信号量变量?

   import java.util.*;

   class Producer
   extends Thread
   {
     private Vector v;

     public Producer(Vector v)
     {
       this.v = v;
     }

     public void run()
     {
       String s;

       while (true) {
         synchronized (v) {
           s = "Value"+Math.random();
           v.addElement(s);
           System.out.println("Producer created "+s);
           v.notify();
         }
         try {
           Thread.sleep((int)(100*Math.random()));
         } catch (InterruptedException e) {
           //nothing
         }
       }
     }
   }

   class Consumer
   extends Thread
   {
      private Vector v;

      public Consumer(Vector v)
      {
         this.v = v;
      }

      public void run()
      {
         while (true) {
            synchronized (v) {
               if (v.size() < 1) {
                  try {
                     v.wait();
                  } catch (InterruptedException e) {
                     //nothing
                  }
               }
               System.out.print(
                 " Consumer found "+(String)v.elementAt(0)
               );
               v.removeElementAt(0);
               System.out.println(" (remaning: "+v.size()+")");
            }
            try {
               Thread.sleep((int)(100*Math.random()));
            } catch (InterruptedException e) {
               //nothing
            }
         }
      }
   }

如果有人可以帮助我,我会很高兴!

提前谢谢..

2 个答案:

答案 0 :(得分:3)

将信号量视为可以允许多个线程访问共享资源的锁。无论您初始化信号量的数量是多少,都允许多个线程同时访问资源。在Producer-Consumer中,资源是两个线程之间的共享缓冲区。您希望确保使用者无法访问缓冲区,除非它已满,并且生成器无法访问缓冲区,除非它是空的。你应该从消费者的信号量中的0开始,到生产者的信号量中的1开始。生产者必须做出第一步。当Producer开始写入缓冲区时,您需要down Producer信号量。生成器完成后,您需要up消费者的信号量,这将允许消费者访问资源。当消费者访问资源时,然后up生产者的信号量通知生产者缓冲区现在是空的。

以此为出发点:http://cs.gmu.edu/cne/modules/ipc/aqua/producer.html

答案 1 :(得分:0)

import java.util.Vector;
import java.util.concurrent.Semaphore;

public class Main {
    public static void main(String[] args) {
        Semaphore mutex = new Semaphore(1);
        Vector<String> vector = new Vector<>();
        new Producer(vector, mutex).start();
        new Consumer(vector, mutex).start();
    }
}

class Producer extends Thread {
    private Vector v;
    private Semaphore mutex;

    public Producer(Vector v, Semaphore mutex) {
        this.v = v;
        this.mutex = mutex;
    }

    public void run() {
        String s;

        while (true) {
            try {
                mutex.acquire();
                s = "Value" + Math.random();
                v.addElement(s);
                System.out.println("Producer created " + s);
                mutex.release();
                Thread.sleep((int) (100 * Math.random()));
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }

        }
    }
}


class Consumer extends Thread {
    private Vector v;
    private Semaphore mutex;

    public Consumer(Vector v, Semaphore mutex) {
        this.v = v;
        this.mutex = mutex;
    }

    public void run() {
        while (true) {
            try {
                mutex.acquire();
                if (v.size() > 0) {
                    System.out.print(" Consumer found " + (String) v.elementAt(0));
                    v.removeElementAt(0);
                    System.out.println(" (remaning: " + v.size() + ")");
                }
                mutex.release();
                Thread.sleep((int) (100 * Math.random()));
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
    }
}