2014-11-21 3 views
0

저는 리프트 컨트롤러를 쓰고 있습니다. 현재 리프트 개체와 사람 개체를위한 두 개의 스레드로 작업하고 있습니다. 둘 다 wait/notify를 사용하여 액션을 올바르게 명령하는 리프트 컨트롤러 클래스를 호출합니다. 여러 개인 스레드와 하나의 리프트 스레드로 작동하도록하고 싶습니다. 따라서 두 번째 사람 스레드가 리프트를 요청하면 현재 사람 스레드가 일시 중지 가능한 지점에 도달 할 때까지 기다려야합니다.스레드를 한 번에 하나씩 실행하는 방법은 무엇입니까?

문제는 notify() 메서드가 어떤 스레드에 통지되는지를 지정하지 않는다는 것입니다. 이것을 어떻게 극복해야합니까? 통지는 오직 임의의 사람 스레드에 통지하는 대신 리프트 스레드와 인터리빙 중이라는 사람의 스레드에만 통지합니다. 대기열에 있습니까?

감사합니다.

+0

내 대답하고 볼 수있는 실행 가능한 예제를 확인하십시오. – Jaskey

답변

0

대기중인 모든 스레드는 사용자 정의 우선 순위를 가질 수 있습니다. 1 인칭 대기 - 1, 2 인칭 대기 - 2.

대기중인 모든 Person 스레드를 깨우는 알림을 브로드 캐스트 할 수 있지만 각 대기 스레드는 자신의 우선 순위를 검사하여 우선 순위 값을 1 씩 감소시킵니다. 0이면 처리를 시작하고 그렇지 않으면 다시 대기합니다. 대기열에서

0
  1. 를 사용하여 여러 Condition 객체 (5 월 아마도 그 자물쇠와 함께). 이것은 시그널을 통지하는 것입니다 만, Object에는 단 하나의 조건 오브젝트 만 있기 때문에 직접 처리해야합니다. 이동하기 전에 monitor을 확인하십시오.

  2. 모든 단일 스레드 (첫 번째 스레드 예상)가 대기열로 이동하여 헤드를 폴링 한 다음 해당 조건을 기다리고 있습니다.

  3. Person 스레드가 완료된 후 다음 상태 객체에 신호를 보냅니다 (다음 스레드가 이에 대기 중입니다).

이 예제는 당신을 도울 수 있습니다

public class LiftController { 
    static LiftThread lift = new LiftThread(); 

    static ReentrantLock liftLock = new ReentrantLock(true); 
    static Queue<Lock> q = new ConcurrentLinkedQueue<Lock>(); 

    static boolean isLiftisAvailable() { 
     return lift.isAvailable(); 
    } 

    static synchronized void ocupyLift() { 
     lift.setAvailable(false); 
    } 

    static synchronized void releaseLift() { 
     lift.setAvailable(true); 
    } 

    public static void main(String[] args) throws InterruptedException { 

     PersonThread person1 = new PersonThread("person1"); 
     PersonThread person2 = new PersonThread("person2"); 
     PersonThread person3 = new PersonThread("person3"); 
     PersonThread person4 = new PersonThread("person4"); 
     List<PersonThread> persons = Arrays.asList(person1, person2, person3,person4); 
     lift.start(); 
     for (PersonThread person : persons) { 
      person.start(); 
     } 

    } 

} 

class PersonThread extends Thread { 

    public PersonThread(String name) { 
     this.setName(name); 
    } 

    public void run() { 
     System.out.println(this.getName() + " begins"); 
     LiftController.liftLock.lock(); 
     System.out.println(this.getName() + " gets liftLock"); 
     Lock lockToWait = LiftController.q.poll(); 
     if(lockToWait!=null){ 
      System.out.println(this.getName() + " tring to get lockToWait of "+lockToWait); 
      lockToWait.lock(); 
      System.out.println(this.getName() + " get lockToWait of "+lockToWait); 
      Condition conditionToWait=lockToWait.newCondition(); 

      if(conditionToWait!=null){//not the first one 
       while (!LiftController.isLiftisAvailable()){ 
        try { 
         System.out.println(this.getName()+" awaiting = "+conditionToWait); 
         conditionToWait.await(); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     } 

     try { 
       System.out.println(this.getName() + " holds the lift==========="); 
       LiftController.q.add(new ReentrantLock()); 
       Lock lockToNofity=LiftController.q.peek(); 
       lockToNofity.lock(); 
       Condition conditionToNotify = LiftController.q.peek().newCondition(); 
       System.out.println(this.getName()+" next notify = "+conditionToNotify); 
       System.out.println(this.getName() + " release the lift"); 
       LiftController.ocupyLift(); 
       LiftController.releaseLift(); 
       LiftController.liftLock.unlock(); 
       System.out.println(this.getName() + " liftLock.unlock"); 
       if(conditionToNotify!=null){ 
        System.out.println(this.getName()+" signaling "+conditionToNotify); 
        conditionToNotify.signal(); 
        lockToNofity.unlock(); 

       } 
     } 

     finally { 
      if(lockToWait!=null) 
       lockToWait.unlock(); 

      System.out.println(this.getName() + " finish"); 
     } 

    } 
} 

class LiftThread extends Thread { 
    private volatile boolean isAvailable = false; 

    public synchronized boolean isAvailable() { 
     return isAvailable; 
    } 

    public synchronized void setAvailable(boolean available) { 
     isAvailable = available; 
    } 

    public void run() { 
     int random = new Random().nextInt(3)+1; 
     while (true) 
      try { 
    //   System.out.println("---------lift is doing his job-----------"); 
       Thread.sleep(random * 1000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
    } 
} 

출력 : 그것은 당신이 원하는 경우

person1 begins 
person1 gets liftLock 
person1 holds the lift=========== 
person3 begins 
person4 begins 
person2 begins 
person1 next notify = java.u[email protected]191c0b76 
person1 release the lift 
person1 liftLock.unlock 
person1 signaling java.u[email protected]191c0b76 
person3 gets liftLock 
person1 finish 
person3 tring to get lockToWait of [email protected][Locked by thread person1] 
person3 get lockToWait of [email protected][Locked by thread person3] 
person3 holds the lift=========== 
person3 next notify = java.u[email protected]5115a298 
person3 release the lift 
person3 liftLock.unlock 
person4 gets liftLock 
person3 signaling java.u[email protected]5115a298 
person4 tring to get lockToWait of [email protected][Locked by thread person3] 
person3 finish 
person4 get lockToWait of [email protected][Locked by thread person4] 
person4 holds the lift=========== 
person4 next notify = java.u[email protected]31eeeaed 
person4 release the lift 
person4 liftLock.unlock 
person2 gets liftLock 
person4 signaling java.u[email protected]31eeeaed 
person2 tring to get lockToWait of [email protected][Locked by thread person4] 
person4 finish 
person2 get lockToWait of [email protected][Locked by thread person2] 
person2 holds the lift=========== 
person2 next notify = java.u[email protected]5bd44ae9 
person2 release the lift 
person2 liftLock.unlock 
person2 signaling java.u[email protected]5bd44ae9 
person2 finish 
관련 문제