import java.io.*;
import java.util.concurrent.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.Callable;
class _TimeOut_ extends PrintIn_Delays {
public static void main(String[] args)
throws InterruptedException {
TimeWait Timeout = new TimeWait();
String input = Timeout.readLine();
String input2 = Timeout.readLine();
}
}
class Reader implements Callable<String> {
public String call() throws IOException {
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
String input;
do {
input = br.readLine();
}while ("".equals(input));
return input;
}
}
class TimeWait extends _TimeOut_ {
public String readLine() throws InterruptedException {
ExecutorService ex = Executors.newSingleThreadExecutor();
String input = null;
try {
try {
Future<String> result = ex.submit(
new Reader());
input = result.get(5, TimeUnit.SECONDS);
} catch (ExecutionException e) {
e.getCause().printStackTrace();
} catch (TimeoutException e){}
} finally {
ex.shutdownNow();
}
System.out.println(" "+input);
return input;
}
}
This will wait for 5 seconds for user input. If user don't enter anything, it displays null.
Now the problem is :
When I run it, it waits for 5 seconds for my input but I don't enter anything and so output is null. Then in the second input, I enter 'hi'. But it still waits for 5 seconds ( which it shouldn't) and after taking the input, it still displays null. Here is the output :
null
hi
null
The problem is that even though you are stopping waiting for the first Future to get a value, it doesn't stop waiting for a value. The BufferedReader.readLine() call simply blocks, waiting for input, or closure of the input stream, irrespective of the timeout.
So, when you do eventually enter a value, the first thread gets it; then there is nothing for the second thread to read.
(But, of course, the second thread hasn't stopped waiting either: this will continue to wait for input, or closure of the input stream).
Related
Once user entered data timer stops and BuferredReader closed.
If 10 seconds passed and no input - BuferredReader closed and user unable to make input. Below code works, but not 100% correct.
Please suggest any solution.
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
NewThread nt = new NewThread(br);
Thread newThread = new Thread(nt);
newThread.start();
System.out.print("Please enter data: ");
System.out.println("");
String value = br.readLine();
System.out.println(value);
nt.shutdown();
}
}
class NewThread implements Runnable {
volatile BufferedReader br;
volatile boolean running ;
public NewThread(BufferedReader br) throws IOException {
this.br = br;
this.running = br.ready();
}
#Override
public void run() {
int count = 10;
try {
while (!running) {
System.out.print("("+count +")"+ '\r');
Thread.sleep(1000);
count--;
if (count <0){
shutdown();
}
}
} catch (InterruptedException | IOException e) {
e.printStackTrace();
}
}
public void shutdown () throws IOException {
running=true;
br.close();
}
}
So, firsty you calling method:
br.readLine()
BufferedReader implementation of this method uses synchornized block when waiting for user input. Below I put part of code this method:
String readLine(boolean ignoreLF) throws IOException {
StringBuffer s = null;
int startChar;
synchronized (lock) {
ensureOpen();
...}
Nextly, when you call method shutdown from NewThread(after time out) on your reader, which call close method on buffer - execution of this metod uses synchronized mechanism too:
public void close() throws IOException {
synchronized (lock) {
if (in == null)
return;
try {
in.close();
} finally {
in = null;
cb = null;
}
}
}
so it means that close method will be executed after finished readLine method (exactly after execution synchronized block in readLine method), which is finished when you pass parameter to console.
I suppose that is not possible to close this reader after calling readLine method by standard java mechanism when you use System.in.
I want to stop and skip a command while it's waiting for input after 3.5 seconds. I have tried to use System.currentTimeMillis() by subtracting from the start time, however the code I made does not skip the input.
food is an arrayList from the table class.
public void timer() {
startTime = System.currentTimeMillis();
while(false||(System.currentTimeMillis()-startTime)<3500)
{
correct = input(); //What I want to skip after 3.5 seconds
}
record();
}
Here is the input() method:
public boolean input()
{
Scanner console = new Scanner (System.in);
//I want to skip everything after this after 3.5 seconds.
int num = console.nextInt();
num--;
System.out.println("You selected " + table.food.get(num).toString());
table.food.remove(num);
if (num==choice)
{
return true;
}
return false;
}
One of the problems you are facing is that any of the Scanner's next methods can not be interrupted when reading from a console. Therefore you have to read the input in a different way, for example by using a InputStreamReader.
After that you can submit a specific task to a ExecutorService that handels the execution of the "input reading" seperately from the main Thread. You will get a Future on which you can define a timeout.
Note that this operation is still blocking (on both threads).
This solution is somewhat based on this article.
import java.io.*;
import java.util.concurrent.*;
public class Test {
static class ReadInput implements Callable<Integer> {
public Integer call() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
while (br.ready() == false) {
Thread.sleep(250);
}
String input = br.readLine();
return Integer.parseInt(input);
} catch (InterruptedException e) {
return null;
}
}
}
public static void main(String[] args) {
Integer input = null;
ExecutorService ex = Executors.newSingleThreadExecutor();
try {
Future<Integer> future = ex.submit(new ReadInput());
input = future.get(3500, TimeUnit.MILLISECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException e) {
// handle exceptions that need to be handeled
} finally {
ex.shutdownNow();
}
System.out.println("done: " + input);
}
}
Note that timeout in the ReadInput should be lower than the timeout in the main Thread.
I'm trying to do this: The question is displayed in the console. If during some time the user does not write the answer, then the next question is asked. If the user enters an answer, the next question is asked immediately. My code:
public class Test {
private boolean stopQuestion;
Thread scannerThread = new Thread();
public static void main(final String[] args) {
final Test test = new Test();
test.scannerThread = new Thread(new Runnable() {
#Override
public void run() {
try {
String string;
do {
string = test.requestInput(new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(3000);
} catch (final InterruptedException e) {
}
test.scannerThread.interrupt();
}
}));
} while (!test.stopQuestion);
System.out.println("Input: " + string);
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
});
test.scannerThread.start();
}
public String requestInput(final Thread timer) throws IOException {
final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
timer.start();
System.out.println("Any question");
System.out.println("Please type your answer: ");
try {
while (!br.ready()) {
Thread.sleep(100);
}
} catch (final InterruptedException e) {
System.out.println("Time is over. Next question: ");
return null;
}
System.out.println("Thank You for providing input!");
return br.readLine();
}
}
If you do not write anything to the console, everything seems to work as expected. Time ends and the next question is asked. But if something is written to the console, the timer starts to malfunction and the next question does not wait for the specified amount of time, sometimes it does not wait at all. I do not understand what's the matter.
I created instance of thread outside the method and pass instance to the method as reference but then throws IllegalThreadStateException.
I see two major problems with your code:
You are continously creating threads that are supposed to read input:
do {
string = test.requestInput(new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(3000);
} catch (final InterruptedException e) {
e.printStackTrace();
}
test.scannerThread.interrupt();
}
}));
} while (!test.stopQuestion); // <-- this is always true
You are opening as many BufferedReaders on System.in as many timer threads you are launching:
final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Also, you are not closing any of these BufferedReader instances.
I want to read multiple lines from an inputstream socket.
public void sendAsync(HashSet<Socket> socketHashset, Vector<String> vectors,
PrintWriter printwriter) throws IOException, InterruptedException {
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(() -> {
for(Socket v : socketHashset){
//this.printwriter = new PrintWriter(v.getOutputStream(),true);
for(String str: vectors ){
this.printwriter.println(str);
this.printwriter.flush();
}
}
});
/* Receiver */
while(true){
try {
printWriter.println(keybordScanner.nextLine())
while(scannerBuffer.hasNextLine()){
System.out.println(scannerBuffer.nextLine());
}
} catch(NoSuchElementException e){
e.printStackTrace();
}
}
}
The problem is that the compiler is blocking then is checking "hasNextLine"
while(scannerBuffer).hasNextLine())
How can i solutionate this issue? some alternatives.
scannerBuffer.hasNextLine() will not return false if there is no next line, but will wait for a line, in which case will return true, or for the socket to close, in which case it will return an exception. If you want your program to be able to do something else while waiting for input, make a Thread for reading input. The thread will be blocked while waiting for input, but the rest of your program won't.
Thread readingThread=new Thread(new readFromSock(scannerBuffer));
readingThread.start();
and make another class:
class readFromSock implements Runnable{
Scanner scannerBuffer;
public readFrom(Scanner scan){
scannerBuffer=scan;
}
public void run(){
try {
while(scannerBuffer.hasNextLine()){
System.out.println(scannerBuffer.nextLine());
}
} catch(NoSuchElementException e){
e.printStackTrace();
}
}
}
I'm creating this program to test getting user input in a thread for a chat server program. This program stops on read = into.readLine();. Why is that and what's happening?
Here is the code:
import java.io.*;
import java.net.*;
public class ThreadClass implements Runnable
{
DataInputStream in;
private boolean checkLoop = false;
public void run()
{
BufferedReader into = new BufferedReader(new InputStreamReader(System.in));
String read;
System.out.println("Welcome...");
while(!checkLoop)
{
try
{
System.out.println("running1");
read = into.readLine();
System.out.println(read);
if(read.equals(".bye"))
{
checkLoop = true;
}
Thread.sleep(500);
}
catch(IOException e)
{
System.out.println(e);System.out.println("running2");
}
catch (InterruptedException ie)
{
System.out.println(ie);System.out.println("running3");
}
}
System.out.println("running4");
}
public static void main(String[]args)
{
ThreadClass main = new ThreadClass();
Thread t1 = new Thread(main);
t1.start();
}
}
When you use "read = into.readLine();" the program will stop and wait for the user to press the "Enter" key. Your program is working fine from my point of view.
Try to type something in console and you will see the program running correctly.