Standard output when using multiple threads - java

I am using eclipse, and when I run it normally I don't see a printed statement in the console, but when I run it in debug mode, I see it. What is going on?
This happens only with some print statements (on the server side of a server-client school project, both being run on local host).
private class GameDriver extends Thread {
private Board board;
public GameDriver() {
board = new Board();
}
#Override
public void run() {
boolean twoActivePlayersAlreadyJoined = false;
while (!twoActivePlayersAlreadyJoined) {
twoActivePlayersAlreadyJoined = connector.activePlayers.size() >= 2;
}
System.out.println("Two players already connected, ready to start game");
sendBoardStateToAll();
}
}

The Eclipse debug window shows different JVMs started from your Eclipse instance.
If you start more than one application in Eclipse, then there will be more than one JVM shown in the debug window as well. Now, if you select one of the JVMs in the debug window the output console changes to the selected JVM's standard output.
Without debug mode, however, Eclipse just displays the standard output of the JVM's console which has printed to standard output last.

Q: I am using eclipse, and when I run it normally I don't see a printed statement in the console, but when I run it in debug mode, I see it. What is going on?
It's entirely possible for a "printf" written from a child thread to remain buffered until the thread is terminated. In which case you'll never see it.
SUGGESTION:
Try "System.err.println()" instead. This uses unbuffered I/O. You might see everything you expect.

connector.activePlayers.size() makes it look like connector.activePlayers is a collection. Is it a thread-safe collection? (And even if it's not a collection, is it it thread-safe?) If not, it could be that connector.activePlayers.size() is constantly returning 0 or 1, resulting in your while loop spinning forever. If this is happening, you might be seeing CPU usage shoot up -- is that the case? Anyway, you can easily check by putting a System.out.println("foo") in the while loop.
It could well be that the debugger is inserting synchronization points or otherwise causing CPU registers, cache, etc to get flushed. That could explain why you're seeing the loop terminate (and thus the System.out.println output) in a debugger, but not in "normal" mode where the JVM is more aggressive about optimization.

Related

Java debug without breakpoint

Is it possible to debug a running java process (with Eclipse / IntelliJ) without having a breakpoint? Would be useful to get the state of an object when having a construct like this:
double d = Math.random();
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.take();
"take()" will block forever, and I'd like to get the value of d with the debugger after take() was called.
I'd like to get the value of d with the debugger after take() was called
A simple solution would be to print the value. Then you don't need the debugger at all. The debugger is useful when changing data due to testing something, inspecting certain objects at runtime etc.
queue.take();
System.out.println(d);
In your case it's not option. One option you can have is to de-compile the jar containing BlockingQueue class, convert them to source files, include it in your project, and set breakpoints inside take() to see the behavior.
One best decompiler is:
http://jd.benow.ca/
using this you can see source of take() function and copy whole class and paste it in your package with name BlockingQueue.java and paste whole source and debug as you wish.
Viewing the state of a thread after an error would be very useful; and while it is more common in some interpreted languages it is sadly lacking in Java. There are however four approaches that come to mind, however bare in mind that the standard approach here in Java is to log important state for later diagnostics.
journal your system, and keep all processing idempotent and deterministic.
attach a debugger after the error; you will not be able to roll back to the point of the exception but you will be able to inspect the current state of the system
add a repl to your server, one that you can telnet into and inspect the system with
Investigate DVR solutions for Java, such as http://chrononsystems.com. They allow rollback of the system to the point of the exception.
Just noticed that there is a pause / suspend button in Eclipse and IntelliJ. This is doing the job.

Debug-Execution Adventure

I debugged my java code. It didn't give any errors.But when i executed it (it isn't giving errors either, but) the code didn't successfully terminate. This is very funny. But is that even possible?
sure, when the slowdown introduced by debugger does mask some race condition, but this normally only applies to multi-threading or networking code.
Yes it is possible that code works when debugging and doesn't work when running. Two possible reasons I can think of right now are
Concurrency in case of multithreading: if your debugger stops on a breakpoint, timing between multiple threads can change which can influence the behaviour
When debugging, you can trigger certain parts of the code multiple times (more than when it has been executed without debugging), like for example via the toString method or via doing inspects or having some watch expression configured
Yes, your code can be syntactically correct (and thus might run without any errors) but may be semantically incorrect.
Assume the following:
public int add( int operand1, int operand2)
{
return operant1 - operand2;
}
This would run without errors but still be incorrect due to logic/implementation error.
So, it IS possible to get wrong results by otherwise smoothly running code.

Why does my application stop running, while it has a while(true) loop?

I have an application that is meant to "run forever". To achieve that, my code is under a while(true) loop.
while(true){
//My code is here
//What it does is that it calls some Url,
//gets xml, parses it and stores the values to a db.
}
This application runs as a java application and runs on jdk 5 on Redhat Linux. After a day or two, I realize that the log has activities of even 5 days ago, meaning that it stopped working 5 days ago. But when I check the java processes in the machine, this application shows that it is running.
Question: Why is this so??
A probable cause is that an exception is being thrown while processing those urls which is cought and consumed by your code, so the processing is failing but the application continues running. Unfortunately you have shown only comments, not any real code, so this is only a hypothesis.
There are many possibilities, but without more code I can't precisely narrow it down to which one specifically it is. Here are some thoughts:
There could be a break statement somewhere in the loop that explicitly leaves the loop.
If your loop is in a function and something in the loop returns from the function, you would leave the loop.
If something in the loop throws an uncaught exception, the loop would terminate. This also includes things like OutOfMemoryErrors or StackOverflowErrors.
The JVM might have crashed overnight due to an unusual bug.
An external process killed the JVM.
The system rebooted to install an update or because someone logged in and ran sudo reboot now.
The laws of boolean arithmetic changed, and now true == false. :-)
Log the exception:
try{
while(true){
// ......
}
}catch(Throwable t){
//log the Throwable object
}

How to quit a java app from within the program

What's the best way to quit a Java application with code?
You can use System.exit() for this purpose.
According to oracle's Java 8 documentation:
public static void exit(int status)
Terminates the currently running Java Virtual Machine. The argument serves as a status code; by convention, a nonzero status code indicates abnormal termination.
This method calls the exit method in class Runtime. This method never returns normally.
The call System.exit(n) is effectively equivalent to the call:
Runtime.getRuntime().exit(n)
System.exit(0);
The "0" lets whomever called your program know that everything went OK. If, however, you are quitting due to an error, you should System.exit(1);, or with another non-zero number corresponding to the specific error.
Also, as others have mentioned, clean up first! That involves closing files and other open resources.
System.exit(int i) is to be used, but I would include it inside a more generic shutdown() method, where you would include "cleanup" steps as well, closing socket connections, file descriptors, then exiting with System.exit(x).
System.exit() is usually not the best way, but it depends on your application.
The usual way of ending an application is by exiting the main() method. This does not work when there are other non-deamon threads running, as is usual for applications with a graphical user interface (AWT, Swing etc.). For these applications, you either find a way to end the GUI event loop (don't know if that is possible with the AWT or Swing), or invoke System.exit().
Using dispose(); is a very effective way for closing your programs.
I found that using System.exit(x) resets the interactions pane and supposing you need some of the information there it all disappears.
I agree with Jon, have your application react to something and call System.exit().
Be sure that:
you use the appropriate exit value. 0 is normal exit, anything else indicates there was an error
you close all input and output streams. Files, network connections, etc.
you log or print a reason for exiting especially if its because of an error
The answer is System.exit(), but not a good thing to do as this aborts the program. Any cleaning up, destroy that you intend to do will not happen.
There's two simple answers to the question.
This is the "Professional way":
//This just terminates the program.
System.exit(0);
This is a more clumsier way:
//This just terminates the program, just like System.exit(0).
return;
Runtime.getCurrentRumtime().halt(0);
System.exit() will do what you want. But in most situations, you probably want to exit a thread, and leave the main thread alive. By doing that, you can terminate a task, but also keep the ability to start another task without restarting the app.
System.exit(ABORT);
Quit's the process immediately.
This should do it in the correct way:
mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
mainFrame.addWindowListener(new WindowListener() {
#Override
public void windowClosing(WindowEvent e) {
if (doQuestion("Really want to exit?")) {
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.dispose();
}
}

Calling function when program exits in java

I would like to save the programs settings every time the user exits the program. So I need a way to call a function when the user quits the program. How do I do that?
I am using Java 1.5.
You can add a shutdown hook to your application by doing the following:
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() {
// what you want to do
}
}));
This is basically equivalent to having a try {} finally {} block around your entire program, and basically encompasses what's in the finally block.
Please note the caveats though!
Adding a shutdown hook addShutdownHook(java.lang.Thread) is probably what you look for. There are problems with that approach, though:
you will lose the changes if the program aborts in an uncontrolled way (i.e. if it is killed)
you will lose the changes if there are errors (permission denied, disk full, network errors)
So it might be better to save settings immediately (possibly in an extra thread, to avoid waiting times).
Are you creating a stand alone GUI app (i.e. Swing)?
If so, you should consider how you are providing options to your users how to exit the application.
Namely, if there is going to be a File menu, I would expect that there will be an "Exit" menu item.
Also, if the user closes the last window in the app, I would also expect it to exit the application.
In both cases, it should call code that handles saving the user's preferences.
Using Runtime.getRuntime().addShutdownHook() is certainly a way to do this - but if you are writing Swing applications, I strongly recommend that you take a look at JSR 296 (Swing Application Framework)
Here's a good article on the basics: http://java.sun.com/developer/technicalArticles/javase/swingappfr/.
The JSR reference implementation provides the kind of features that you are looking for at a higher level of abstraction than adding shutdown hooks.
Here is the reference implementation: https://appframework.dev.java.net/

Categories