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 ]"); } } } } 21 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.