java readlineのキーボード入力の終了を数秒後に自動で行うには?
解決済
回答 2
投稿
- 評価
- クリップ 0
- VIEW 2,966
前提・実現したいこと
java
コマンドラインで、表示された、数字の列の合計を計算するプログラムを
作成しています。
発生している問題・エラーメッセージ
正解不正解の分岐とともに、数秒たったら時間切れと表示して、
次の問題にいくようにしたいのですが、
readlineの要求が残ってしまい、何か入力しないと次の問題にいけません。
初歩的な問題で申し訳ございません。
お分かりになる方いらっしゃればお教え頂けると大変にありがいたいです。
該当のソースコード
import java.io.*;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
public class keisan_traning {
static long sum_time = 0;
public static void main(String[] args) {
long sum = 0;
//long static sum_time = 0;
int Correctanswer1 =0;
System.out.println("陽輝三角");
// 配列の宣言。
//なんいどが高すぎるので、for文を外して一か所にする①
for(int k=0;k<5;k++){
int a,b,c;
a =(int)( Math.random()*1000 ) % 3+2;
b =(int)( Math.random()*1000 ) % 3+2;
int C[][] = new int[a][b];
for( int i=0; i<a; i++ ) {
for( int j=0; j<b-i; j++ ){
c =(int)( Math.random()*1000 ) % 100+1;
C[i][j] = c;
sum = sum + C[i][j];
}
}
// 九九の結果を表示。
for( int i=0; i<a; i++ ) {
for( int j=0; j<b-i; j++ ) {
System.out.print(C[i][j] + " ");
}
System.out.println();
}
//なんいどが高すぎるので、for文を外して一か所にする②
//}
System.out.println("合計を答えよ");
long start = System.currentTimeMillis () ;
TimerTask task = new TimerTask() {
public void run() {
System.out.println("時間切れです");
//long time =stop-start;
keisan_traning.sum_time=keisan_traning.sum_time+10000L ;
}
};
Timer timer = new Timer();
timer.schedule(task, 10000L);
try {
BufferedReader input =
new BufferedReader (new InputStreamReader (System.in));
String str2 = input.readLine( );
long stop = System.currentTimeMillis () ;
try{
int str3 = Integer.parseInt(str2);
if(str3==sum){
System.out.println( "正解" );
System.out.println( "正解。掛かった時間は" );
long time =stop-start;
System.out.println(TimeUnit.MILLISECONDS.toSeconds(time)+"秒");
//System.exit(0);
Correctanswer1 ++;
keisan_traning.sum_time= keisan_traning.sum_time+time;
}else if(str3!=sum){
System.out.println( "不正解" );
System.out.println( "正解は" );
System.out.println(sum);
System.out.println( "不正解。掛かった時間は" );
long time =stop-start;
System.out.println(TimeUnit.MILLISECONDS.toSeconds(time)+"秒");
//System.exit(0);
keisan_traning.sum_time= keisan_traning.sum_time+time;
}
}catch(NumberFormatException e){
System.out.println("数値でない値が入力されています");
long time =stop-start;
keisan_traning.sum_time= keisan_traning.sum_time+time;
}
} catch ( IOException e) {
System.out.println( "キーボードが故障しているのかもしれません" );
}
}
System.out.println("正解は5問中で"+Correctanswer1+"問でした");
System.out.println("合計時間は"+TimeUnit.MILLISECONDS.toSeconds(keisan_traning.sum_time)+"秒でした");
System.exit(0);
}
}
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
若干 複雑ですが、以下のようにコンソールからの入力を受け付ける処理(Worker
クラス内の処理)を別スレッドで実行してやれば、タイムアウトを実現できます。
https://docs.oracle.com/javase/jp/6/api/java/util/concurrent/Future.html#get(long, java.util.concurrent.TimeUnit)
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Worker());
// 10秒でタイムアウトさせる
long timeout = 10;
try {
String result = future.get(timeout, TimeUnit.SECONDS);
System.out.println("入力値は" + result);
} catch (TimeoutException e) {
future.cancel(true);
System.out.println("タイムアウトしました。");
} finally {
executor.shutdown();
}
}
private static class Worker implements Callable<String> {
@Override
public String call() throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
return reader.readLine();
}
}
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
String str2 = "時間切れ!";
Boolean flag = True;
Calendar end = Calendar.getInstance();
end.add(Calendar.SECOND, 30);
while(Calendar.getInstance().before(end)){
if(input.ready()){
str = input.readLine();
flag = False;
break;
}
Thread.sleep(1);
}
if(flag){
System.out.println("時間切れです。")
}
long stop = System.currentTimeMillis();
こうすれば、30秒以内に入力がない(input.read()の戻り値が1度もTrueにならなかった場合)にflagがTrueのままになり、時間切れです。というメッセージが表示されるはずです。
参考: http://www.javaspecialists.eu/archive/Issue153.html
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.32%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2016/05/16 19:15
大変にありがとうございました。
少し自分には高度なので、じっくり読み込んで比較して理解して、
この考え方を使いこなせるようになりたいと思います。
また、分からなければご質問させて頂きます。
大変にありがとうございました。
2016/05/16 19:57
知らないクラスやメソッドが出てきたら、まずはAPIリファレンスを読んでみることをお勧めします。
例えば今回、私が提示させていただいたプログラムを理解するためには、以下を読んでみると良いでしょう。
https://docs.oracle.com/javase/jp/6/api/java/util/concurrent/Executors.html
https://docs.oracle.com/javase/jp/6/api/java/util/concurrent/ExecutorService.html
https://docs.oracle.com/javase/jp/6/api/java/util/concurrent/Future.html
https://docs.oracle.com/javase/jp/6/api/java/util/concurrent/Callable.html
ぜひ、頑張ってください。