Java Scanner Input in Separate Thread
I Have a Multi-Threaded Command Line App. It Is a Web Service Client with a Pool of 10 Threads That Churns Away, Sending Requests, Batch-Style, to a Server...
I have a multi-threaded command line app. It is a web service client with a pool of 10 threads that churns away, sending requests, batch-style, to a server.
But it runs for a few days, and sometimes further down the pipeline, the queues start getting backed up. So I want to go to the client, press - or + and have that increase or decrease a Thread.sleep(waitingTime), to take pressure off the server.
I tried running a Scanner in a separate thread, but it didn't seem to work. Has anyone managed to get non-blocking I/O working in Java? I presume it's possible, but I'm giving up for now.
Edit: Added test code as per request
package test;
import java.io.*;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by djb on 2015/06/03.
*/
public class ThreadTest {
public ThreadTest() {
}
static long rand = 10000;
public static void main(String args[])
{
ExecutorService executor = Executors.newFixedThreadPool(5);
File f = new File("C:\\code\\ThreadTest\\text.csv");
try {
Runnable keyPressThread = new ThreadTest.KeyPressThread();
Thread t = new Thread(keyPressThread);
t.start();
BufferedReader br = new BufferedReader(new FileReader(f));
String line;
while ((line = br.readLine()) != null)
{
try {
final String copy = line;
executor.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(rand);
Thread.sleep(rand);
System.out.println(copy);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
} catch (Exception e)
{
e.printStackTrace();
}
}
} catch (Exception e)
{
e.printStackTrace();
}
}
public static class KeyPressThread implements Runnable {
Scanner inputReader = new Scanner(System.in);
//Method that gets called when the object is instantiated
public KeyPressThread() {
}
public void run() {
String input = inputReader.next();
if (input.equals("["))
{
rand+=100;
System.out.println("Pressed [");
}
if (input.equals("]"))
{
rand-=100;
System.out.println("Pressed ]");
}
}
}
}
1 Answer
Your KeyPressThread is only testing once:
This will make it watch constantly.
public void run()
{
while(true)
{
if (inputReader.hasNext())
{
String input = inputReader.next();
if (input.equals("["))
{
rand+=100;
System.out.println("Pressed [");
}
if (input.equals("]"))
{
rand-=100;
System.out.println("Pressed ]");
}
if (input.equalsIgnoreCase("Q"))
{
break; // stop KeyPressThread
}
}
}
}
System.in is line buffered, by default. This means that no input is actually passed to the program until you press ENTER.