0

내 질문에 대해 매우 감사 드리며, 매우 혼란스럽고 쉽게 해결할 수있는 문제로 인해 좌절하고 있습니다. 정말 도움이 될 것입니다.Scanner에서 제공하는 조건에 따라 스레드가 동작을 수행하도록하려면 어떻게해야합니까?

내가 원하는 것은 닫혀 있거나 열리는 장벽의 두 가지 인스턴스를 가지려는 것입니다. 장벽이 열려야하는지 확인하는 방법은 스캐너를 통해 이루어 지므로 1을 클릭하면 메시지 "입학 장벽"+ threadid + 내가 main 메소드를 실행 할 때마다

public class MainClass{ 
    public static void main(String[] args) { 

     EntranceBarrier e1 = new EntranceBarrier(); //Entrance Barrier 1 
     EntranceBarrier e2 = new EntranceBarrier(); //Entrance Barrier 2 

     e1.start(); 
     e2.start(); 

     System.out.println("Open?"); 
     Scanner sc = new Scanner(System.in); 
     int operation = sc.nextInt(); 


     while(operation != 0){ 

      switch (operation) { 
       case 1: 
        e1.setOpen(true); 
        e2.setOpen(true); 
        System.out.println("Opt. 1 Working"); 
        break; 
       case 2: 
        e1.setOpen(false); 
        e2.setOpen(false); 
        System.out.println("Opt. 2 Working"); 
        break; 
       default: 
        System.out.println("NOPE"); 
        break; 
      } 

     System.out.println("Open?"); 
     operation = sc.nextInt(); 
     } 


    } 
    } 

이 처음 "입학 장벽 청산"을 인쇄하고 내가 스캐너에 입력 한 단지 수신 거부. 1 "을 출력합니다 작업"개설 " "이것은 setOpen()을 true로 변경하지 않음을 의미합니다.

+0

메인 스레드 외에는 여기에서 스레드를 사용하고 있지 않습니다. 모든 열기 및 닫기 작업은 주 스레드에서 수행됩니다. 응용 프로그램이 시작되고 5 초 후 EntranceBarrier 스레드가 종료됩니다. – hal

답변

0

: 그것은 D를 나를 찢어되고있어, 난 정말 당신이 나를 도울 수 있기를 바랍니다,

import java.io.*; 
import java.util.Scanner; 

public class EntranceBarrier extends Thread { 

    private volatile boolean open = false; 

    public synchronized void OpenBarrier(){ 
    if(isOpen()){ 
     try{ 
      String threadid = Thread.currentThread().getName(); 
      System.out.println("Entrance Barrier " + threadid + " Opened"); 
      Thread.sleep(5000); 
     }catch(InterruptedException e){ 
      e.printStackTrace(); 
     } 
     } else{ 
      System.out.println("Entrance Barrier Closed"); 

     } 

    } 

    public void run() { 
     OpenBarrier(); 
    } 

    public boolean isOpen() { 
     return open; 
    } 

    public void setOpen(boolean open) { 
     this.open = open; 
    } 

} 

이 질문은 충분히 명확 경우 나도 몰라 : 여기

는 EntranceBarrier 클래스의 나는 몇 가지 변화를 제안하고자한다.

우선 모든 입구 스레드 이름 싶습니다 입구 스레드의 상태 변화 정보를 유지하기위한 요구 및 가변 경우

import java.util.Scanner; 

public class MainClass { 
public static void main(String[] args) { 

    EntranceBarrier e1 = new EntranceBarrier(); // Entrance Barrier 1 
    e1.setName("Bar1"); 
    EntranceBarrier e2 = new EntranceBarrier(); // Entrance Barrier 2 
    e2.setName("Bar2"); 

    e1.start(); 
    e2.start(); 

    System.out.println("Open?"); 
    Scanner sc = new Scanner(System.in); 
    int operation = sc.nextInt(); 

    while (operation != 0) { 
     switch (operation) { 
     case 1: 
      e1.setOpen(true); 
      e2.setOpen(true); 
      System.out.println("Opt. 1 Working"); 
      break; 
     case 2: 
      e1.setOpen(false); 
      e2.setOpen(false); 
      System.out.println("Opt. 2 Working"); 
      break; 
     default: 
      System.out.println("NOPE"); 
      break; 
     } 

     System.out.println("Open?"); 
     operation = sc.nextInt(); 
    } 
} 
} 

다음 제가 활성 검사를 만들기 위해 루프를 추가 할 것이다.

import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.ReentrantLock; 

public class EntranceBarrier extends Thread { 

    private volatile boolean open = false; 
    private volatile boolean requestedState = false; 

    private Lock lock = new ReentrantLock(); 

    public void OpenBarrier() { 
     try { 
      lock.lock(); 
      printState(); 
      lock.unlock(); 

      while (true) { 
       lock.lock(); 
       if (requestedState != open) { 
        printState(); 

        Thread.sleep(5000); 
        open = requestedState; 

        printState(); 
       } 
       lock.unlock(); 
       Thread.sleep(100); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
      lock.unlock(); 
     } 
    } 

    private void printState() { 
     if (requestedState == open) { 
      if (open) 
       System.out.println("Entrance Barrier " + getName() + " Opened"); 
      else 
       System.out.println("Entrance Barrier " + getName() + " Closed"); 
     } else { 
      if (requestedState) 
       System.out.println("Entrance Barrier " + getName() + " Opening"); 
      else 
       System.out.println("Entrance Barrier " + getName() + " Closing"); 
     } 
    } 

    public void run() { 
     OpenBarrier(); 
    } 

    public boolean isOpen() { 
     return open; 
    } 

    public void setOpen(boolean open) { 
     if (lock.tryLock()) { 
      this.requestedState = open; 
      lock.unlock(); 
     } else { 
      System.out.println("Entrance Barrier " + getName() + " is moving"); 
     } 
    } 
} 

synchronized 키워드 대신에 재진입 잠금을 사용하여 잠금이 이미 잠겨 있는지 확인합니다. 입구의 상태가 변경되면 setOpen 함수를 종료 할 수 있습니다.

wait()/notify()를 사용하면 EntranceBarrier를 더 업그레이드 할 수 있습니다. 능동적 인 대기는보다 효율적인 방법으로 대체 될 수 있습니다.