Java input without pausing - java

How would I make a sort of console for my program without pausing my code? I have a loop, for example, that needs to stay running, but when I enter a command in the console, I want the game to check what that command was and process it in the loop. The loop shouldn't wait for a command but just have an if statement to check if there's a command in the queue.
I'm making a dedicated server, by the way, if that helps.

Have them run in two separate threads.
class Server {
public static void main(String[] args) {
InputThread background = new InputThread(this).start();
// Run your server here
}
}
class InputThread {
private final Server server;
public InputThread(Server server) {
this.server = server;
}
public void run() {
Scanner sc = new Scanner(System.in);
while(sc.hasNextLine()) {
// blocks for input, but won't block the server's thread
}
}
}

There's pretty obvious approach: use a dedicated thread to wait on InputStream, read events/commands from it and pass them into a queue.
And your main thread will be regularly checking this queue. After every check it will either process a command from the queue or continue what it was doing if it's empty.

What you'd like to have is a thread in which you keep the command reading code running. It'd probably look something like this:
class ReadCommand implements Runnable
{
public void run()
{
// Command reading logic goes here
}
}
In your "main" thread where the rest of the code is running, you'll have to start it like this:
new Thread(new ReadCommand())).start()
Additionally, you need a queue of commands somewhere which is filled from ReadCommand and read from the other code.
I recommend you to read a manual on concurrent java programming.

The server should run in its own thread. This will allow the loop to run without pausing. You can use a queue to pass commands into the server. Each time through the loop the server can check the queue and process one or more commands. The command line can then submit commands into the queue according to its own schedule.

You can read from the console in a separate thread. This means your main thread doesn't have to wait for the console.
Even server applications can have a Swing GUI. ;)

Related

Java - How to create a subprocess in a class that is running a method

I'm writing a program that enables UDP communication between a KUKA robot (programmed in java) and a python server running on a PC. The program on the robot needs to run multiple methods concurrently because it needs to listen/receive messages on 3 sockets simultaneously (they all need to be listening for messages at all times).
I first tried this using multi-threading. My main class is DP_UDP_COMM which start running when the robot is started. When starting some initialization between the robot and python server is done to set up the socket connection, after that the communication processes need to be started. An example of 1 of these 'communication' threads is shown below as Thread UDP_COMM:
//DP_UDP_COMM class is the main class that gets started when the robot starts
public class DP_UDP_COMM extends RoboticsAPITask {
//Some code here
//One of the communication processes that needs to run while the DP_UDP_COMM instance is active
public Thread UDP_COMM = new Thread(new Runnable(){
public void run(){
while(running){
_log.info("Thread Started, Waiting for Action");
try {
ReceiveUDP();
_log.info("Buffer received is: "+String.valueOf(receive));
_log.info("Type received is: "+String.valueOf(ByteProcess.getType(receive)));
if(status==0)
processPacket(receive);
} catch (Exception e) {
// TODO Auto-generated catch block
send = createPacketResponse("ERROR: "+e.getMessage());
try {
SendUDP(send);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace(); }
e.printStackTrace();
}
}
}
});
UDP_COMM.start();
//Some code and other methods here
}
This thread tries to receive a UDP message from a socket using ReceiveUDP(). This is a blocking method so it keeps waiting here untill it receives a message. This message is then processed using processPacket(), which is a method that sends a command to the robot determined by the message that was received. After sending the command it starts listening again for new messages. This loops indefinitely when the robot is active.
The other threads are very similar but use slightly different methods which are bound to different sockets.(For example ReceiveUDPEmergency() which is the same as ReceiveUDP() but with a different socket)
This is working well with one thread, but when running 3 threads concurrently it doesn't work anymore because the threads will wait for each other to complete before looping because ReceiveUDP() is a blocking method.
The solution for this (I think) is to use multi-processing instead of multi-threading because this truly runs them in parallel instead of sequentially.
However when looking at the java.lang.Process documentation I really don't get how creating a process works. In every example they create/start a process from an external .exe file or something like that.
Is it possible to create multiple processes that run multiple methods in parallel within my DP_UDP_COMM instance? How would I do this?
//What have I tried:
As explained above I tried multi-threading at first. But this isn't good enough.
With multi-processing it is not clear how to start a process which just runs a method in parallel to the main instance.

How can I stop a Java Thread from another one?

Maybe I'm thinking to complicated, but I have the following situation:
I have a class Server.java extending Thread with the following relevant part of the code:
public void run() {
while(listening) {
try {
ServerThread cst = new ServerThread(serverSocket.accept());
cst.start();
} catch (IOException e) {
listening = false;
System.out.println(e.getMessage());
}
}
}
My ServerThread then handles all the incoming stuff.
My question now is, if there is any possibility to stop this Thread (Server) like for example over the command line.
I tried to add a new class, that would handle command line input and .interrupt() this Thread, but that kinda just made a big mess..
Here's one way:
Provide a setter for listening that can be accessed from another class/thread.
Set a reasonable timeout (say, 1 sec) on the ServerSocket and handle the SocketTimeoutException.
To stop the thread, set listening to false and within 1 second the thread will stop. If you want finer control, investigate the async I/O classes in java.nio.
You can define listening as volatile, with a setter and set that to false from another class whenever you want to stop the Thread.

Java how to persist a process reference so I can run process.destroy()

I want to start a webservice via an executible jar I create (so that I can eventually use procrun to have it start up as a Windows Service). The webservice is currently started via the command line by calling the main method on the class.
Here is my code so far:
public class test
{
private static boolean stop = false;
private static Process process;
public static void start(String[] args)
{
String classpath = "my\\classpath\\test.jar";
ProcessBuilder processBuilder = new ProcessBuilder("C:\\java\\jdk1.6.0_43\\bin\\java",
"-cp", classpath,
"com.test.theJavaWebServiceWithAMainMethod");
try
{
process = processBuilder.start();
}
catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
public static void stop(String[] args)
{
stop = true;
process.destroy();
}
public static void main(String[] args)
{
if (args != null && args.length > 0)
{
String command = args[0];
if ("start".equals(command))
{
start(args);
}
else if ("stop".equals(command))
{
stop(args);
}
}
else
{
throw new IllegalArgumentException("command missing");
}
}
}
Starting works fine. I see the process start in the task manager and I can now pull up the WSDL. However when I go to kill the process via process.destroy() (by calling the main method with the arguemnt stop), I get a null pointer exception I assume because this is a new instance of the jvm so it doesn't know the process from when I called start. Whats the best way to persist this process object or pid or something so when I go to call stop, I can find and kill the webservice (java process) that is running?
You are executing your 'test' program twice, which results in two completely separate program instances, and they have no reference to each other. So when you call the 'test' program with stop command, theprocess variable is null because one was not created in the current program.
Options:
Rewrite your main method to block, waiting for the "stop" command. This would mean the start/stop were not separate asynchronous program executions though. You would start the program, and it would then wait for you to enter a stop command before exiting.
You could devise a way to signal the other application 'remotely' ...even though it's all running on the same machine. This is easy to do via a simple network socket, and is a very common approach. (Checkout Tomcat's start/stop command handling for an example....though it's more complex than you need.) To summarize... once running, the main program listens on a server socket. The subsequent "stop program" connects to that server socket as client to notify the main program it should stop.
You could use underlying OS tools to find and stop the program. See this answer: How to find and kill running Win-Processes from within Java? . It's hard to do cross platform and generically though.
It's not really clear what it is you want to do though and why you are executing your web service as a separate program via ProcessBuilder. Depending on your requirements, perhaps you could instead do something like this:
public void start(String[] args)
{
try
{
com.test.theJavaWebServiceWithAMainMethod.main(args);
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
That would start your service, of course, and then you could control-c to end the program.
Rather than start your runnable jar as you do, you could convert your program to start as a Windows Service. Then it would be able to react to a Windows-based shutdown request.

Executing batch from Java

Let's say,
I have a Java class JavaClass1.java.I am executing 2 batch files from this Java class.
Each .bat files starts another Java application.
Lets say these other two app takes 15 hour each to complete, and they are also not dependent to each other.
How can I solve this issue. I dont have to wait for one to complete so that I have to
start another, I can do it simultaneously also.
I found people talking about handelling outputstream, inputstream and error stream, if I
wait for the errors to handle, then I have to wait 15 hours for each. I dont want to do that.
Is there any way? Please suggest. Thanks
Place the mechanism for launching each .bat in its own thread, then start each thread.
new Thread(new Runnable() {
#Override
public void run() {
//Launch first bat.
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
//Launch second bat.
}
}).start();
Runtime.getRuntime().exec(new String[]{"cmd","/c","java -jar app1.jar"});
Runtime.getRuntime().exec(new String[]{"cmd","/c","java -jar app2.jar"});
Just use Runtime execute service, if you don't call process.waitFor() to get return code of process, it won't blocking, so you can call next app immediately. If you want return code from app, run app on each Thread as Mike.

About multi threading

How to kill the thread?
.....
How to restart them again in multi threading?
Since your post is tagged "Java," I have a good idea of what you are saying. Let's say you start a thread by doing:
Thread foo = new Thread(someRunnable);
foo.start();
Now that destroy and friends are deprecated, you need a way to kill the thread. Luckily for you, there has always been the concept of "interrupts." Simply change your runnable so that, on interrupt, it exits. Then call the thread's interrupt method.
foo.interrupt();
If you wrote your Runnable to handle this correctly, it will stop whatever it is doing and terminate.
Thread.stop() kills a thread, but you definitely don't want to do this (see the API documentation for an explanation why). Thread.interrupt() sends an asynchronous notification to a thread, so that it can shut itself gracefully.
For a comprehensive text on Java multithreading, I recommend B. Goetz, Java Concurrency in Practice, Addison-Wesley Professional.
The preferred way for a Thread to die is for the execution of the run method to go to completion:
Thread t = new Thread(new Runnable() {
public void run() {
// Do something...
// Thread will end gracefully here.
}
}
Once a thread gracefully dies in the example above, the Thread cannot be restarted. (Trying to call Thread.start on a thread that has already been started will cause an IllegalThreadStateException.)
In that case, one can make another instance of the thread and call start on that.
Probably a good place to get more information on threading would be Lesson: Concurrency from The Java Tutorials.
i wrap my worker threads up in their own class and use a terminated property to kill the thread proc loop.
sorry i dont have a java version to hand right now but you should get the idea from this
http://pastie.org/880516
using System.Threading;
namespace LoaderDemo
{
class ParserThread
{
private bool m_Terminated;
private AutoResetEvent m_Signal;
private string m_FilePath;
...
public ParserThread(AutoResetEvent signal, string filePath)
{
m_Signal = signal;
m_FilePath = filePath;
Thread thrd = new Thread(this.ThreadProc);
thrd.Start();
}
public bool Terminated {
set { m_Terminated = value; }
}
private Guid Parse(ref string s)
{
//parse the string s and return a populated Guid object
Guid g = new Guid();
// do stuff...
return g;
}
private void ThreadProc()
{
TextReader tr = null;
string line = null;
int lines = 0;
try
{
tr = new StreamReader(m_FilePath);
while ((line = tr.ReadLine()) != null)
{
if (m_Terminated) break;
Guid g = Parse(ref line);
m_GuidList.Add(g);
lines++;
}
m_Signal.Set(); //signal done
}
finally
{
tr.Close();
}
}
}
}
The best way to kill a thread is to set up a flag for the thread to watch. Program the thread to exit when it sees the flag is set to true. There's no way to restart a killed thread.
If you want to start, stop, restart threads at will, maybe using the Java 5 concurrency package would be a good idea. You can have an Executor that will do a bit of work, and when you need that bit of work to be done again, you can just re-schedule it to be done in the executor.
Regarding your first query on killing thread:
You can find more details about topic in below SE questions:
How to properly stop the Thread in Java?
How can I kill a thread? without using stop();
How to start/stop/restart a thread in Java?
Regarding your second query of re-starting thread, it's not possible in java.
You can find below details in documentation page
public void start()
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
The result is that two threads are running concurrently: the current thread (which returns from the call to the start method) and the other thread (which executes its run method).
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
Instead of plain Threads, you can use advanced concurrent API for thread life cycle management. Have a look at this post for ExecutorService details :
How to properly use Java Executor?

Categories

Resources