0

私の質問を見ていただきありがとうございます、私は非常に混乱しており、おそらく簡単な解決策がある問題に苛立ち、私は本当に助けていただければ幸いです。Scannerが提供する条件に基づいてスレッドがアクションを実行するにはどうすればよいですか?

私が望むのは、バリアが開いているかどうかを判断する方法は、スキャナを使用しているかどうかを判断する方法です。1をクリックすると、メッセージ私はそれが最初の「エントランスバリアクローズ」とするとき、それは唯一の「オプトを出力スキャナへのI入力1を出力mainメソッドを実行するたびに「エントランスバリア」+スレッドID +が

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に変更しませんでした。

はここEntranceBarrierクラスです:

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; 
    } 

} 

私はこの質問は十分にクリアされている場合、私は本当にあなたが私を助けることができると思いますかわからない、それはDに私を引き裂くされています:

+0

メインスレッドの他に、ここでスレッドを使用していません。すべてのオープン操作とクローズ操作は、メインスレッドで実行されます。アプリケーションが起動し、5秒後にEntranceBarrierスレッドが終了します。 – hal

答えて

0

私はいくつかの変更を提案したいと思います。

まず、私はすべての入り口スレッドに名前を付けたいと思います:入学スレッドの状態の変化は、この情報を保持するための要求と、可変された場合

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をアップグレードできます。アクティブな待機をより効率的な方法で置き換えることができます。

関連する問題