Read from stdin but unable to know when to stop - java

I am running some commnads on commmand prompt. I am waiting for the last command's output to complete. I have to read the output and perform the operation. My command's output is very dynamic and I can not predict when I can stop reading.
I am having issues that I dont know when to stop reading. If suppose I keep the while read(), then my last command output is not ending with new line. Is there any mechenism which can tell me if there has been no activity on stdin for last 5mins, then I get some alert??

The approach I took was to create a class implementing Runnable which monitors the value of a shared AtomicInteger flag. This InputRunnable class sleeps for 5 minutes (300000 ms) and then wakes up to check whether the value has been set by the main method. If the user has entered at least one input in the last 5 minutes, then the flag would be set to 1, and InputRunnable will continue execution. If the user has not entered an input in the last 5 minutes, then the thread will call System.exit() which will terminate the entire application.
public class InputRunnable implements Runnable {
private AtomicInteger count;
public InputRunnable(AtomicInteger count) {
this.count = count;
}
public void run() {
do {
try {
Thread.sleep(300000); // sleep for 5 minutes
} catch (InterruptedException e) {
// log error
}
if (count.decrementAndGet() < 0) { // check if user input occurred
System.exit(0); // if not kill application
}
} while(true);
}
}
public class MainThreadClass {
public static void main(String args[]) {
AtomicInteger count = new AtomicInteger(0);
InputRunnable inputRunnable = new InputRunnable(count);
Thread t = new Thread(inputRunnable);
t.start();
while (true) {
System.out.println("Enter a number:");
Scanner in = new Scanner(System.in);
int num = in.nextInt(); // scan for user input
count.set(1);
}
}
}
I tested this code locally and it appears to be working, but please let me know if you have any issues getting it to run on your system.

Related

While loop in Java doesn't break when pressing Enter, when condition is a DataInputStream.isAvailable() == 0 and the application runs with telnet

I am trying to simulate a "ping" command in Java. I extracted only lines which I consider relevant for my question. So, when running this code, it is printed "Pinging..." once per second, until the user presses ENTER. After ENTER is pressed, it is printed in console "Exit ping." and the application stops. The problem is when the application runs using telnet, the button ENTER doesn't have any effect. Note: the entire application is an OSGi application, and it may run both using telnet or not using it, so in both cases I should have the same behaviour. It works fine only if telnet is not used.
DataInputStream dis = new DataInputStream(System.in);
System.out.println("Press Enter to stop.");
while (dis.available() == 0) {
System.out.println("Pinging...");
Thread.sleep(1000);
}
System.out.println("Exit ping.");
If I add at the end of "while" loop
System.out.println(dis.available())
without telnet, it prints 0, and when ENTER is pressed it prints a value != 0. With telnet, even if ENTER is pressed, the value is 0.
dis.available() will not actually check for user input its not a read.
You will need to actually wait for the user input on a separate thread as you want to continue the loop in the main thread. example below
import java.util.Scanner;
public class GeneralMain {
private static boolean exit = false;
public static void main(String[] args) throws InterruptedException {
System.out.println("Press Enter to stop.");
Thread t = new Thread(new ReadFromCmd());
t.start();
while (!exit) {
System.out.println("Pinging...");
Thread.sleep(1000);
}
System.out.println("Exit ping.");
}
static class ReadFromCmd implements Runnable {
#Override
public void run() {
Scanner s = new Scanner(System.in);
s.nextLine();
exit = true;
}
}
}

How can i make pause option in java

Now I'm using java to create Timer program.
But the problem is..
I want to add pause option in my program but i cannot find How to add pause option..
So Please give me some advice on how to insert a pause option..
import java.util.Scanner;
public class HelloWorld {
public static void main(String[] args) throws InterruptedException {
Scanner sc = new Scanner(System.in);
System.out.println("Please enter Minutes : ");
int min = sc.nextInt();
long sec = min * 60;
for(long i = sec; i >= 0; i--) {
if(i % 30 == 0) {
System.out.println(i/60 + " min" + i%60 + " sec");
}
Thread.sleep(1000);
}
System.out.println("Timer is over..");
}
}
I'm assuming you want to give the user the option to enter something and cause the countdown to pause. The problem (I think) is that if you ask for input, then that will block the current thread of execution, hence your timer will freeze.
To solve this, you need some form of asynchronous execution. You might want to take a look at Timer: you can use this to schedule a callback to occur every second. This callback function could print the next number in the countdown sequence, while your main thread waits for user input and cancels the timer if the user types pause.

How can I implement a separate thread that assesses user input while a loop is running in main? [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I'm designing a print queue program that randomly generates print jobs and, depending on each individual print job's time, "prints" them out for a few seconds, suspending the main thread while another thread continually checks whether the user has pressed the enter key, generating a new print job to be added to the end of the queue in the main thread, or the "Q" button, signalling to end the program. Here is the relevant bit of code:
Scanner input = new Scanner(System.in);
AdPrint addPrint = new AdPrint();
addPrint.start();
for (int i = 0; i < printQueue.size(); i++)
{
System.out.println("Printing " + i + " of " + printQueue.size()
+ "\n" + printQueue.get(i).getJobTime()
+ " seconds remaining."
+ "\nPlease press \"Enter\" to submit a new print"
+ " job or \"Q\" to quit.");
addPrint.setI(i);
addPrint.setInput(input);
addPrint.setJobGen(jobGen);
addPrint.setPrintQueue(printQueue);
Thread.currentThread().sleep(printQueue.get(i).getJobTime() * 1000);
printQueue.add(addPrint.getPrintQueue().get(i));
addPrint.interrupt();
}
AdPrint (which I intentionally misspelled because of another problem I had in eclipse; I changed this class in DropBox on another computer and because there was a new copy, eclipse didn't recognize it as AddPrint for some reason so I had to rename the class to make it work, but that's not the problem here) is the separate thread that handles user input during the waiting period. Before I get into that, I just want to note that I originally had addPrint.start(); in the for loop with no interrupt method, but I realized what would happen is that java would then create infinitely many parallel threads in some sort of runaway feedback loop. I just thought that the values of addPrint (the instance) would just change but that was not the case. Now for AdPrint:
import java.util.LinkedList;
import java.util.Random;
import java.util.Scanner;
public class AdPrint extends Thread
{
private Scanner input;
private Random jobGen;
protected LinkedList<PrintJob> printQueue;
int i;
private boolean run = true;
private String choice = new String();
public void run()
{
while (run)
{
if (input.nextLine() != null)
{
this.choice = input.nextLine();
if (choice.equalsIgnoreCase("q"))
{
for (int i = 0; i < printQueue.size(); i++)
{
System.out.println(printQueue.get(i).toString());
}
}
else if (choice.equalsIgnoreCase("\\n"))
{
int printTime = jobGen.nextInt(10);
PrintJob job = new PrintJob();
job.setJobNum(i);
job.setJobTime(printTime);
printQueue.add(job);
}
}
else if (input.nextLine() == null) {
this.choice = input.nextLine();
}
}
}
Now as it stands, I get the following NullPointerException at if (input.nextLine() != null):
Exception in thread "Thread-0" java.lang.NullPointerException
at AdPrint.run(AdPrint.java:19)
I am new to threads and would like some help here after spending some time tinkering with this. Why am I getting this exception? How do I make this thread, addPrint, check to see if the user has requested another print job?
EDIT:
I forgot to mention that I have getter/setter methods for AdPrint:
public void setInput(Scanner input)
{
this.input = input;
}
In your main() you call start() before you call setInput:
Scanner input = new Scanner(System.in);
AdPrint addPrint = new AdPrint();
addPrint.start();
This means that the Scanner will still be uninitialized and therefore still be null. You must call setInput before you call start(). To test this you can add a print statement right before you call input.nextLine() to see that input is indeed null

Time limited for user input [duplicate]

I'm writing a testing system and i all i want to do is to count how many seconds had user spent on this question. i.e. i print question(standard System.out.println), then wait 5 seconds and if within these 5 seconds user answered(through standard input), i want to keep this value.
If user hasn't provided an answer in 5 seconds, it must skip this question and continue.
The problem is I'm reading user answers via Scanner object, and something like in.nextInt() is uncontrollable, I suppose.
How can I solve this problem? Here is fragment of my code without that functionality, can you give me some hints what to add?
public void start() {
questions.prepareQuestions(numQuestions);
Scanner in=new Scanner(System.in);
boolean playerIsRight=false,botIsRight=false;
int playerScore=0,botScore=0;
for (int i = 0; i < numQuestions; i++) {
questions.askQuestion(i);
System.out.print("Your answer(number): ");
playerIsRight=questions.checkAnswer(i,in.nextInt()-1); //in.nextInt() contains the answer
botIsRight=botAnswersCorrectly(i + 1);
if(playerIsRight){ playerScore++; System.out.println("Correct!");}
else System.out.println("Incorrect!");
if(botIsRight) botScore++;
System.out.print("\n");
}
if(botScore>playerScore) System.out.println("Machine won! Hail to the almighty transistors!");
else if(playerScore>botScore) System.out.println("Human won! Hail to the power of nature!");
else System.out.println("Tie. No one ever wins. No one finally loses.");
}
I would use two threads in this case. The main thread writes questions, waits for answers, and keeps score. A child thread reads standard input and sends the answers to the main thread, perhaps via a BlockingQueue.
The main thread can wait for five seconds for an answer by using the poll() method on the blocking queue:
…
BlockingQueue<Integer> answers = new SynchronousQueue();
Thread t = new ReaderThread(answers);
t.start();
for (int i = 0; i < numQuestions; ++i) {
questions.askQuestion(i);
System.out.print("Your answer (number): ");
Integer answer = answers.poll(5, TimeUnit.SECONDS);
playerIsRight = (answer != null) && questions.checkAnswer(i, answer - 1);
…
}
t.interrupt();
If this call returns null, the main thread knows that the child thread didn't receive any input during that time, and can update the score appropriately and print the next question.
The ReaderThread would look something like this:
class ReaderThread extends Thread {
private final BlockingQueue<Integer> answers;
ReaderThread(BlockingQueue<Integer> answers) {
this.answers = answers;
}
#Override
public void run() {
Scanner in = new Scanner(System.in);
while (!Thread.interrupted())
answers.add(in.nextInt());
}
}
Used on System.in, the Scanner will block until the user presses Enter, so it might happen that the user has entered some text but not yet pressed Enter when the main thread times out and moves on to the next question. The user would have to delete their pending entry and enter a new answer for the new question. I don't know of a clean way around this awkwardness, since there's not a reliable way to interrupt the nextInt() call.

Java how to synchronize 2 threads?

SOLVED !
I have a homework. I will say shortly what is about. I have to read from .txt file few numbers, and multiply them. I need to use threads and synchronize that multiplication only. I done that already and my homework ends here! But, I want to go ahead and create a more complex way for example:
I have in .txt numbers like this: 5, 6, 2, 11, 24, 10,
and then I multiply them like this 5*6*2*11*24*10 .
How can I create 2 threads, Thread #1 for numbers, and Thread #2 for multiply, and print them in console like this:
Thread #1 running, number is 5
Thread #2 running, multiply is 5
Thread #1 running, number is 6
Thread #2 running, multiply is 30
Thread #1 running, number is 2
Thread #2 running, multiply is 60
I really appreciate any suggestion, past 10 h since I work at this and still can't get it work.
class MyThread extends Thread {
Thread thread;
MyThread(String name) {
thread = new Thread(this, name);
}
public synchronized void numbers(boolean running) {
if (!running) {
notify();
return;
}
notify();
try {
FileInputStream fs = new FileInputStream("in.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fs));
String line;
int numbers = 0;
while ((line = br.readLine()) != null) {
String[] splitter = line.split("\\s");
numbers = Integer.parseInt(splitter[0]);
for (int i = 0; i <= splitter.length - 1; i++) {
numbers = Integer.parseInt(splitter[i]);
System.out.print("\nIn " + thread.getName() + "number is " + numbers + "\t");
Thread.sleep(500);
}
}
} catch (InterruptedException e) {
System.out.println("main thread interrupted");
} catch (IOException e) {
System.out.println("main thread interrupted");
}
}
public synchronized void multiply(boolean running) {
if (!running) {
notify();
return;
}
notify();
try {
FileInputStream fs = new FileInputStream("in.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fs));
String line;
int numbers = 0;
int multiply = 1;
while ((line = br.readLine()) != null) {
String[] splitter = line.split("\\s");
numbers = Integer.parseInt(splitter[0]);
for (int i = 0; i <= splitter.length - 1; i++) {
numbers = Integer.parseInt(splitter[i]);
multiply = multiply * numbers;
System.out.print("\nIn " + thread.getName() + " multiply is " + multiply + "\t");
Thread.sleep(500);
}
}
} catch (InterruptedException e) {
System.out.println("main thread interrupted");
} catch (IOException e) {
System.out.println("main thread interrupted");
}
}
synchronized public void run() {
if (thread.getName().compareTo("Thread #1 ") == 0) {
for (int i = 0; i < 1; i++)
this.numbers(true);
this.numbers(false);
} else {
for (int i = 0; i < 1; i++)
this.multiply(true);
this.multiply(false);
}
}
}
My code look like this:
In main I call like this:
MyThread mt1 = new MyThread("Thread #1 ");
MyThread mt2 = new MyThread("Thread #2 ");
mt1.start();
mt2.start();
At this moment , my output look like this:
In Thread #2 multiply is 5
In Thread #1 number is 5
In Thread #1 number is 6
In Thread #2 multiply is 6
In Thread #2 multiply is 30
In Thread #1 number is 2
In Thread #1 number is 11
In Thread #2 multiply is 660
In Thread #2 multiply is 15840
In Thread #1 number is 24
The problem is that you're trying to use one implementation for both tasks. I would suggest to create ReadThread that will read the input file and MultiplyThread that will wait for some event for example and multiply numbers. Also they will need to share some collection of the numbers (see ConcurrentLinkedQueue for example).
So ReadThread read a number from file, adds it to the queue. At the same time MultiplyThread waits for anything to appear in the same queue and when this happens multiply new number on the previous one. There is also will be improvements on the design, because without much effort we can replace MultiplyThread with let's say AddThread that will calculate sum of the numbers.
However your implementation trying to do both tasks in one class which highly increases complexity. Also try to get rid of synchronized and Thread.sleep statements, in your case they will decrease the performance and there would be no point in using multithreading.
Here is example implementation for the method I've suggested.
First is the ReadThread. It has the queue that will contain numbers that have to be processed. I have simplified the reading of the numbers from the file, you can replace it with you reading implementation.
class ReadThread implements Runnable {
private final String filename;
private final ConcurrentLinkedQueue<Integer> queue;
public ReadThread(ConcurrentLinkedQueue<Integer> queue, String filename) {
this.queue = queue;
this.filename = filename;
}
public void run() {
try {
FileInputStream fs = new FileInputStream(filename);
Scanner scanner = new Scanner(fs);
while (scanner.hasNextInt()) {
int number = scanner.nextInt();
System.out.println("ReadThread read " + number);
queue.add(number);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
And the MultiplyThread. Here we take the number from the queue and multiply it on the result which stores the previous value. There is the problem with thread life cycle - we don't know when it should be stopped. So I have used simple active flag. Which tells the thread when to stop.
class MultiplyThread implements Runnable {
private boolean active = true;
private Integer result = 1;
private final Queue<Integer> queue;
public MultiplyThread(ConcurrentLinkedQueue<Integer> queue) {
this.queue = queue;
}
public void run() {
while (isActive()) {
Integer number = queue.poll();
if (number != null) {
result *= number;
System.out.println("MultiplyThread current result is " + result);
}
}
}
public synchronized void stop() {
active = false;
}
public synchronized boolean isActive() {
return active;
}
}
And here is the last part. It's more complex then yours, because of MultiplyThread interruption.
public static void main(String[] args) throws InterruptedException {
ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<Integer>();
ReadThread readThread = new ReadThread(queue, "numbers.txt");
MultiplyThread multiplyThread = new MultiplyThread(queue);
Thread reader = new Thread(readThread);
Thread multiplicator = new Thread(multiplyThread);
multiplicator.start();
reader.start();
reader.join();
multiplyThread.stop();
multiplicator.join();
}
The result of the program
ReadThread read 1
ReadThread read 2
MultiplyThread current result is 1
MultiplyThread current result is 2
ReadThread read 3
MultiplyThread current result is 6
ReadThread read 4
MultiplyThread current result is 24
ReadThread read 5
MultiplyThread current result is 120
ReadThread read 6
MultiplyThread current result is 720
ReadThread read 7
MultiplyThread current result is 5040
You can see that thread are working concurrently, ReadThread does not wait MultiplyThread to calculate the result for all previous values.
It is not clear what you are trying to do. There are some obvious mistakes in the code which i want to highlight (and hence writing this answer), but I can't answer the question as the code seems to do what it was written to do: it runs 2 threads, both read from the same file and output results of reading in slightly different ways.
Now to the problems:
1) if you are extending Thread you should not have a thread field inside of it. Basically you can replace thread = new Thread(this ,name); with super(name).
2) your synchronized doesn't do anything. Synchronized makes method enter a monitor (essentially acquire object lock) when you enter the method and release it when method is done. Your two threads are 2 different instances which share no data between each other, so synchronizeds are not doing anything.
The way you've written your code, the two threads aren't really "connected", they don't share any memory. They read both the same file, but that's all - no shared memory. From what I guess, the idea would rather to have a "producer" thread which reads data from the file, and a "consumer" thread which get data read by the first thread and execute the multiplication. The second thread should not read the file.
You could write something with a shared AtomicInteger: when empty (null), the "producer" thread set it to what it has read ; and when non empty, the "consumer" thread read it, reset it to empty, and can run its multiplication.

Categories