2016-10-29 5 views
1

私は、簡単な質問に時間制限付きの質問をするプログラムを書こうとしています。コンソール入力を待っている間にThread.sleep()を使ってタイマーを作る方法は?

これまでのところ、私は次のようしている:

public static void main(String[]args) throws IOException, InterruptedException{ 
    Thread thread = new Thread(); 
    Scanner scan = new Scanner(System.in); 

    System.out.println("1. What is 1+1?"); 
    System.out.println("a. 2\tb. Cannot Be.\tc. 3\td. All of the above."); 
    String question1 = scan.next(); 
    for(int i = 3; i>=0; i--){ 
     System.out.print("\b"+i); 
     Thread.sleep(1000); 
    } 
} 

この適切に質問をし、答えがかかりますが、それは入力に時間制限をかけていないと後3から0 までカウントダウン入力が与えられる。私は間違って何をしていますか?

+0

以下の答えは – developer

答えて

0

これは、黒マルチスレッドの魔法の少しを使用して行うことができます。 thread1が質問をするとthread2がカウントダウンされたスレッドである

Thread thread1 = Thread.currentThread(); 
Thread thread2 = new Thread(() -> { 
    try { 
     for (int seconds = 3; seconds > 0; seconds--) { 
      System.out.println(seconds+" second"+(seconds == 1 ? "s" : "")+" left"); 
      Thread.sleep(1000); 
     } 
     System.out.println("Time's up!"); 
     thread1.stop(); 
    }catch(InterruptedException weCanIgnoreThisException){} 
}); 

まず、あなたはこのような二つのスレッドが必要になります。

残っていることは質問することです。 入力を受ける前にstart()thread2を忘れずに、入力を受けてstop()にしてください!

System.out.println("1. What is 1+1?"); 
System.out.println("a. 2\tb. Cannot Be.\tc. 3\td. All of the above."); 
thread2.start(); 
String answer = scan.next(); 
thread2.stop(); 

さてさて、私は非推奨メソッドThread#stop()を使用なぜここにあります。

スレッドとスレッドの停止:stop()は非推奨となり、どのような状況が、それはプログラムを台無しにするされている理由

The official documentation of java.lang.Threadは説明しています。停止すると、ロックされているすべてのモニタのロックが解除されます(チェックされていないThreadDeath例外の自然な結果として、スタックの上に伝播します)。以前にこれらのモニターによって保護されたオブジェクトのいずれかが不整合な状態にあった場合、破損したオブジェクトは他のスレッドから見えるようになり、潜在的に任意の動作を引き起こします。要するに

それは​​ブロックまたは方法を使用してオブジェクトにロックされている間、スレッドがstop() PEDである場合、オブジェクトのロックを危険な突然の方法で放出されます。多肢選択式の質問をして入力に時間制限を設定しても、スレッドは​​になる必要はないので、これを無視することができます。

+0

が ..あなたに先生ありがとうございましたが、私は、このオブジェクトを使用する何を知りたい助けなら、私に知らせて" - >"? :) –

+0

(秒== 1? "s": "")とこれ。 :D –

+0

@WenCy '() - {ここにコードを入力}'は[ラムダ式](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html)です(基本的に匿名のクラスです(この場合、['java.lang.Runnable'](http://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html)))と'秒== 1? "s": ""は[三項式](https://en.m.wikipedia.org/wiki/%3F :)です。 – dorukayhan

0

ループ中に別々の関数を呼び出して作成するので、グローバル変数などの宣言が長引くことはありません。ランダムに呼び出されるものを制御する必要がある場合、関数内にrandを置いて、そのようにグローバルなものを使うこともできますし、単にそれらを呼び出して完了させたい順番に並べることもできます。

0

あなたが正しく推測したように、以下の説明のように2つの別々のスレッドが必要です&コード。

以下の説明では、2つのスレッドで何をどのように行う必要があるかについて詳しく説明します。

(1)スレッド1:Timerスレッドが(内部クラスはRunnableを実装して)別のスレッドで実行され、ユーザーの入力を待っている間に秒をカウントします。ユーザーが入力を入力すると、このスレッドは信号(stopTimerが信号として機能する)を使用して停止する必要があり、stopTimer変数がvolatile(スレッド2によって書き込まれたデータを受け取る)であることを確認します。

(2)スレッド2:これはユーザーの入力を待つmain threadです。ユーザがデータを入力すると、このメインスレッド信号は、別のメソッド呼び出しを使用してタイマースレッドを停止する - signalStopTimer()

public class TimerTest {  

     public static class Timer implements Runnable { 

      private volatile boolean stopTimer = false; 

      private long timerMilliSeconds =0; 

      @Override 
      public void run() { 
       try { 
        while(!stopTimer) { 
         Thread.sleep(1000); 
         timerMilliSeconds = timerMilliSeconds+1000; 
        } 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 

      public void signalStopTimer() { 
       stopTimer = true; 
      } 

      //this method will be helpful to find the elapsed time in seconds 
      public long getTotalTimeInSeconds() { 
       return timerMilliSeconds/1000; 
      } 

     } 

     public static void main(String[] args) { 

       TimerTest.Timer timer = new TimerTest.Timer(); 
       //Start the Timer Thread now 
       Thread thread = new Thread(timer); 
       thread.start(); 

       Scanner scan = new Scanner(System.in); 

       System.out.println("1. What is 1+1?"); 
       System.out.println("a. 2\tb. Cannot Be.\tc. 3\td. All of the above."); 
       String input = scan.next(); 

       //received the input, signal to stop timer 
       timer.signalStopTimer(); 
       System.out.println(" input is:"+input+" seconds"); 
       System.out.println(" total time :"+timer.getTotalTimeInSeconds()); 


     } 

    } 
0

ユーザーが入力するまでの時間を計算する必要がある場合は、System.currentTimeMillis()を使用するのが一番簡単な方法です。

あなたが変数の中に現在の時間を保存することができます(ロング)してから、whileループ(ユーザーが入力したときにループ状態が停止する)でループの最後に保存します上記の方法でミリ秒単位で現在の時刻を計算し、残りのすべてを減算します。

これはあなたの方向であれば私はそのためのコードを供給することができます知っている;)

関連する問題