从并发Java信号量中删除sleep()

时间:2015-11-07 22:17:21

标签: java multithreading concurrency semaphore

我正在做一个项目,要求我们将睡眠理发师Java代码Here带回酒店。有几个规则,但我遇到了三个类似的问题:

  1. 线程可能不会使用睡眠作为协调手段
  2. 不允许忙着等待(轮询)
  3. 每个帖子应该只打印自己的活动
  4. 如何删除睡眠方法,以及如何更换它们?

    我想出了这些信号量:

    import java.util.concurrent.Semaphore;
    import java.util.*;
    
    public class Hotel extends Thread {
    
     public static Semaphore deskClerk = new Semaphore(0, false); //semaphore representing the deskClerk
     public static Semaphore guestList = new Semaphore(0);       //semaphore representing the guests.
     public static Semaphore bellHop = new Semaphore(0, false); //semaphore representing the bellHop.
     public static Semaphore accessSeats = new Semaphore(1);   //the seats that the guestList sit down on upon entering the hotel
     int roomCounter = 0; // supposed to be an incrementing global variable integer that increments with each customer acquisition by the front desk employee
     int guestID, bellhopID, clerkID;
    
     // the number of chairs in this hotel is 15. 
     public static final int CHAIRS = 15;
    
     public static int numberOfFreeSeats = CHAIRS;
    

    这些课程:

    访客

     class Guest extends Thread {
      //  we create the integer iD which is a unique ID number for every guest and a boolean notServed which is used in the Guest waiting loop
      int iD;
      boolean notServed = true;
      int baggage;
    
      // Guest Constructor
      public Guest(int name, Hotel h) {
       iD = name;
       guestID = iD;
       Random rn = new Random();
       baggage = rn.nextInt(6);
       //need a random number from 0-5. Represents number of bags.
      }
    
      public int getBaggage() {
          return baggage;
      }
    
      public boolean checkBaggage() {
          if(this.getBaggage() > 2) {
              return true;
          }
          else {
              return false;
          }
      }
    
      public void run() {
       while (notServed) { // as long as the customer has not been served
        try {
         accessSeats.acquire(); // tries to get access to the hotel chairs
         if (numberOfFreeSeats > 0) { // if there are any free seats
          System.out.println("Guest " + this.iD + " has entered hotel with " + this.getBaggage() + " bags");
          numberOfFreeSeats--; // sitting down on a chair
          guestList.release(); // notify the front desk salesmen that there is a customer
          accessSeats.release(); // don't need to lock the chairs
                // anymore
          try {
              roomCounter++;
              deskClerk.acquire(); // now it's this guestList turn
                // but we have to wait if the deskClerk is busy
              notServed = false; // the guest will now leave after they are served.
              this.get_Served(); // Serving the guests
              if (this.checkBaggage() == true){
                  bellHop.release();
                  System.out.println("Guest " + this.iD + " requests help with bags");
                  //from here, need a way for the bellhop to signal the guest that they should tip the bellhop, receive the bags, and retire.
              }
              else {
                  System.out.println("Guest " + this.iD + " enters room #" + roomCounter + " and retires for the evening");
              }
          }
          catch (InterruptedException ex) {
          }
         } 
         else { // there are no free seats
          System.out.println("There are no free seats. Guest " + this.iD + " has left the hotel.");
          accessSeats.release(); // release the lock on the seats
          notServed = false; // the customer will leave since there are no spots in the queue left.
         }
        } catch (InterruptedException ex) {
        }
       }
      }
    
      /* this method simulates a front desk employee processing a guest */
      public void get_Served() {
       System.out.println("Guest " + this.iD
         + " receives room key for room " + roomCounter + " from front desk employee " + clerkID);
       try {
        deskClerk.release();
       }
       finally{
       }
      }
    

         /* THE CLERK THREAD */
    
     class Clerk extends Thread {
         boolean busy = false;
      public Clerk(int name, boolean bus) {
          clerkID = name;
          busy = bus;
      }
    
      // this method will simulate booking rooms 
     public void serve() {
      System.out.println("Front desk employee " + this.getId() + " registers guest " + guestID + " and assigns room " + roomCounter);
      try {
       sleep(3000);
      } catch (InterruptedException ex) {
      }
     }
    
      public void run() {
       while (true) { // runs in an infinite loop
        try  {
         guestList.acquire(); // tries to acquire a customer - if none is available he goes to sleep
         accessSeats.acquire(); // at this time he has been awaken -> want to modify the number of available seats
         numberOfFreeSeats++; // one chair gets free
         deskClerk.release(); // the clerk is ready to serve the customer
         accessSeats.release(); // we don't need the lock on the hotel chairs     anymore
         this.serve(); // serving the customer
        } 
        catch (InterruptedException ex)  {
        }
       }
      }
     }
    

    侍者

         /*THE BELLHOP THREAD */
     class bellHop extends Thread { 
         boolean busy = false;
      public bellHop(int name, boolean f) {
          bellhopID = name;
          busy = f;
      }
    
      public void handleBaggage() {
          if(bellHop.availablePermits() != 0){
           System.out.println("Bellhop " + this.getId() + " receives bags from guest " + guestID);
           System.out.println("Bellhop " + this.getId() + " delivers bags to guest " + guestID);
    
           try {
               bellHop.acquire();
           } 
           catch (InterruptedException ex){
               System.out.println( this.getId() + " Cannot handle baggage");
           }
          }
      }
    
      public void run() {
       while (true) { // runs in an infinite loop
        try {
        this.handleBaggage(); // take baggage up to guests room and receive a tip
        sleep(100);
        } 
        catch (InterruptedException ex) {
        }
       }
      }
     }
    

    Main&酒店跑()

        // main method 
     public static void main(String args[]) {
         System.out.println("Simulation Starts");
         Hotel hotel = new Hotel(); // Creates a new hotel
         Clerk george = hotel.new Clerk(1, false);  System.out.println("Front desk employee " + george.getId() + " created");
         Clerk greg = hotel.new Clerk(2, false); System.out.println("Front desk employee " + greg.getId() + " created");
         bellHop bill = hotel.new bellHop(1, false); System.out.println("Bellhop " + bill.getId() + " created"); 
         bellHop bob = hotel.new bellHop(2, false); System.out.println("Bellhop " + bob.getId() + " created"); 
         hotel.start(); // begins the simulation
         greg.start();
         george.start();
         bill.start();
         bob.start();
     }
    
     public void run() {
         Hotel h = new Hotel();
    
        // This method creates 25 new guests
        for (int i = 1; i < 10; i++) {
            Guest aGuest = new Guest(i, h);
            aGuest.start();
            try {
                sleep(3000);
            }   
            catch (InterruptedException ex) {         
            }
        }
     }
    }
    

1 个答案:

答案 0 :(得分:0)

睡觉意味着浪费时间(或者更具体地说,浪费一个线程)。线程在给定时间结束(或线程中断)之前不执行任何操作。

通常,您不想浪费时间 - 您只是想等待其他事情发生。例如,当没有客人时,店员不想睡觉:相反,店员应该等待客人已经到达的信号,然后立即可以为该客人提供服务。如果你在Java中使用监视器锁,那么职员会在监视器上wait(),直到另一个线程notify()编辑它。

Semaphore可以用来构建正确的并发构造,但它并不适合这种问题。对于&#34;客户(客户)线程的一般问题,每个人都希望从中央调解员(职员)获得资源(房间)&#34;我实际上会使用Future代表&#34;排队等候#34;状态和相应的值。当然,这可能不是你的教授试图通过这项任务教你的技巧。 : - )

在您展示的理发师示例中,以及您的代码中,您还使用睡眠来模拟您实际上并未实际执行的工作 - 例如,理发师没有实际上剪掉任何头发,只是睡了几秒钟来模拟理发需要一些时间。听起来这个任务允许这样做。但是,在现实世界的系统中,你不需要睡眠,只是线程所做的实际工作需要花费大量的时间。