Is there any way to find the execution flow of java code? - java

public class Threads1 {
int x = 0;
public class Runner implements Runnable {
public void run(){
int current = 0;
for(int i = 0; i<4; i++){
current = x;
System.out.println(current + ", ");
x = current + 2;
}
}
}
public static void main(String[] args) {
new Threads1().go();
}
public void go(){
Runnable r1 = new Runner();
new Thread(r1).start();
new Thread(r1).start();
}
}
I want to find the execution step of this code ,Is there any way that can show me the execution flow in my consol?

Print Statements
Put System.out.println() statements in appropriate places in your code. For example, put
System.out.println("Entering a for loop");
before a for loop to know when the for loop is entered.
Debugger
Find out how to set a breakpoint in your IDE. Set a breakpoint at start of the portion of code that you don't understand. When that line is going to be executed, the program will pause and allow you to examine the values in variables, the stack trace, the threads, etc. You can also find out which thread is the current line running on in the debugger.
Additionally, find "Step in", "Step over" and "Step out" buttons on the debugger. These will allow you to "step through" your code line by line, so as to allow you to see the path that execution takes.

Java Threads
If you have several threads running at once ther is no way to predict which one of them finishes first or when something is done, like to differen programms. Different threads are executed by different cores of you CPU and therefore completely independend from oneanother, this affects computation speed and order (branchprediction in you CPU plays one role here). This can lead to pretty difficult bugs to find because they only happen sometimes.
Your Problem
The execution order of the threads is not determend a compile time it's decided by you CPU at runtime and is not consistent because the threads do not know they have a partner.
Solution
To display the order at which it happend just insert System.out.println statements in your methodes and create so a sort of log what happened in you console.
Controled Threads with Synchronized
If you use threads, Java supports the synchronized keyword. Synchronized allows you to get a bit of control over several threads. For example only one thread at a time can interact with a variable or methode. For more information just google Java synchronized threads.

One of the possibilities is to create a field in the class that would differentiate both threads to make you sure which thread prints the values to the console in the moment (you should contain this additional value in the informations you print to the console in the "for" loop to know if the first or the second thread has performed activity printed to the console).
Another possibility is using debugger.

Related

Java Multi Threading Code gets stuck in a normal run mode in IDE but debug mode makes it work

I am new to Java Multi-Threading and was trying to create a program where there are 2 threads. One which prints out Odd Numbers and one which Prints out even numbers. Now, I want all numbers from 1 to 1000 printed in order such that each thread takes a turn. I have created a Turn object which is shared by the 2 objects and hence can be used for signalling 1 thread from the other! The code is given below
public class Turn {
public static int whoseTurn = 1;
public static int getWhoseTurn() {
return whoseTurn;
}
}
public class Main {
public static class EvenThread extends Thread{
#Override
public void run() {
int i = 2;
while(i < 1000){
if(Turn.getWhoseTurn() == 2) {
System.out.println(String.valueOf(i) + " is an even number ");
i = i + 2;
Turn.whoseTurn = 1;
}
}
}
}
public static class OddThread extends Thread{
#Override
public void run() {
int i = 1;
while( i < 1000){
if(Turn.getWhoseTurn() == 1) {
System.out.println(String.valueOf(i) + " is an odd number ");
i = i + 2;
Turn.whoseTurn = 2;
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread evenThread = new EvenThread();
Thread oddThread = new OddThread();
oddThread.start();
evenThread.start();
Thread.sleep(10000);
evenThread.join();
oddThread.join();
}
}
I have 2 issues with this code.
The code when run in a normal run mode gets stuck anywhere from count 380 - 690. But, when run in a debug manner initially without breakpoints again gets stuck there but then if a breakpoint is added after it gets stuck, I understand where the code is and a run button again runs the code. Why does my code get stuck in a normal run mode and how do I avoid that?
Is there a race condition possible for this solution or is this solution a perfect solution for coordination between the threads? I can't think of any case where this code would fail to produce results?
The code when run in a normal run mode gets stuck anywhere from count 380 - 690. But, when run in a debug manner initially without breakpoints again gets stuck there but then if a breakpoint is added after it gets stuck, I understand where the code is and a run button again runs the code. Why does my code get stuck in a normal run mode and how do i avoid that?
^^ this happens because of busy wait. Even thread could be waiting (looping for its turn) never conceding/giving chance to Odd thread to run. And since Odd thread did not run, Even thread would not make any progress - giving the program a stuck state where no progress is being made. You could add a sleep at the end of loops in both threads to solve this (alternatively use wait/notify to avoid time wastage due to sleep). In debug mode, you essentially make a thread to pause (giving chance to other thread to proceed)
Is there a race condition possible for this solution or is this solution a perfect solution for coordination between the threads? I can't think of any case where this code would fail to produce results?
^^ multi threading programs are hard to debug and test. Currently I don't see any issues as well but would recommend comparing it with already available solutions to understand what is being differently with your logic and why.
Rishabh's answer theoretically highlights what could be going wrong. In short, just before things go wrong, one thread (can be either even or odd thread) is printing the odd/even number and then changing the whoseTurn variable so that the next thread can print the other number. However, the problem is with the latter i.e. even though the value is changed in memory, the second thread is somehow unable to read the latest value.
This is because the controlling variable whoseTurn is not a volatile variable. In java, every thread has local copy of variables in the cache. That means every read of the variable is done from the cache which may or may not be equal to the variable's value in the main memory. For Java, “volatile” tells the compiler that the value of a variable must never be cached.
For more information regarding volatile you can refer to oracle documentation page
Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable.
To verify the above, you can add the below line to your program and execute the same.
public volatile static int whoseTurn = 1;

Wait for method to Finish, and weird interaction with System.println

I am trying to write a genetic program to play through a game, but I am running into a bit of a snag. When I call this code:
public double playMap (GameBoard gb, Player p) {
gb.playerController = p;
Game g = new Game(gb);
int initHP = 0;
for (Unit u : gb.enemy.units) {
initHP += u.maxHP;
}
g.playGame(false);
int finalHP = 0;
for (Unit u : gb.enemy.units) {
finalHP += u.currHP;
}
System.out.println(" " + initHP);
System.out.println(" " + finalHP);
System.out.println(" " + (finalHP - initHP));
if (initHP == finalHP) {
return -10;
}
return initHP - finalHP;
}
the g.playGame() line does not have time to finish, and I am getting incorrect results from the function. I can wait out unit the game is over with a
while (!g.isDone) {
System.out.println(g.isDone);
}
but not with the same while loop without a print statement. I know there has to be a more elegant solution, and I cant seem to implement the methods I have seen. Also if anyone knows why I need the print statement in the while loop to get it to wait that would be great too.
Thanks in advance.
ADDED playGame:
public void playGame(boolean visual) {
Global.visual = visual;
if (Global.visual) {
JFrame application = new JFrame();
application.setBackground(Color.DARK_GRAY);
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.add(this);
application.setSize(500, 400); // window is 500 pixels wide, 400 high
application.setVisible(true);
}
PlayerInput pi = new PlayerInput();
this.addKeyListener(pi);
final Timer timer = new Timer(10/60, null);
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
pi.addPressed();
if (update(pi)) {
// application.setVisible(false);
// application.dispose();
System.out.println(gb.toString());
isDone = true;
timer.stop();
}
pi.reset();
}
};
timer.addActionListener(listener);
timer.start();
while (!isDone) {
System.out.println(isDone);
}
}
First of all, this is a really bad way of doing this. This approach is called "busy waiting" and it is very inefficient.
The problem is most likely that reads and writes to g.isDone are not properly synchronized. As a consequence, there are no guarantees that the "waiting" thread will ever see the update to g.isDone that sets it to true.
There are various ways to ensure that the update is seen. The simplest one is to declare isDone as volatile. Another one is to do the reads and writes within a primitive lock.
The reason that the println() call "fixes" things is that println is doing some synchronization behind the scenes, and this is leading to serendipitous cache flushing (or something) that makes your update visible. (In other words: you got lucky, but exactly how you got lucky is hard to tie down.)
A better solution is to use another mechanism for coordinating the two threads.
You could use Thread.join() so that one thread waits for the other one to terminate (completely!).
You could use a Latch or Semaphore or similar to implement the waiting.
You could use an Executor that delivers a Future and then call Future.get() to wait for that to deliver its result.
You could even use Object.wait and Object.notify ... though that is low-level and easy to get wrong.
Without seeing the full context, it is hard to judge which approach would be most appropriate. But they would all be better than busy-waiting.
Another answer says this:
If you remove the System.out.println() call from your loop, I believe that the compiler simply doesn't include the loop in the Java bytecode, believing it to be superfluous.
As I explained above, the real problem is inadequate synchronization. To be technical, there needs to be a happens-before relationship between the write of isDone in one thread and the read of isDone in the other one. Various things will give that ... but without that, the compiler is entitled to assume that:
the writing thread does not need to flush the write to memory
the reading thread does not need to check that the memory has changed.
For example, without the happens-before, the compiler would be permitted to optimize
while (!g.isDone) {
// do nothing
}
to
if (!g.isDone) {
// do nothing
}
We don't know if this actually happens, or whether the actual cause of "non-visibility" of the update to isDone is something else. (Indeed, it could be JVM version / platform specific. To be sure, you would need to get the JIT compiler to dump the native code for the methods, and analyze the code very carefully.)
Apparently you are running your game in a separate thread. Assuming that thread is called foo, calling foo.join() will block the calling thread until foo finishes executing. You can simply replace your entire loop with foo.join().
If you remove the System.out.println() call from your loop, I believe that the compiler simply doesn't include the loop in the Java bytecode, believing it to be superfluous.

Non thread-safe code unexpectedly giving repeatable results

This is a question on a test. I have run the code many times and get the same answer: 999999. They say that this code will not produce the same results every time even though synchronized is present when writing the runLoop method. What am I missing?
public class B extends Thread{
static int a = 0;
public static void main(String[] Args){
B MyB = new B();
MyB.start();
runLoop(1000000);
System.out.println(a);
}
public static synchronized void runLoop(int b){
for(int i = 0; i<b; i++){
a=i;
}
}
public void run(){
runLoop(12345678);
}
}
Usually when you call
SomeThread.start();
it takes some time to properly start thread which allows thread which is executing this command to execute few of its next lines, like
SomeThread.start();//lets say it should print "A"
System.out.print("B");
in many cases will print BA instead of AB and that is what your question is about.
So in case of your code before MyB thread will start(), main thread can invoke its own runLoop(1000000);. Then MyB may run runLoop(12345678); but now main thread may execute System.out.println(a); which is accessing a in unsynchronized way so it may show how many times MyB iterated at current point of time (so both threads are accessing a at the same time which may give different results each time you run your application).
If you claim that you always got as response 999999 then you ware very lucky, or are not showing us your real code (like in case where between MyB.start(); and runLoop(1000000); there is other code which could take enough time to let MyB.start() finish like TimeUnit.SECONDS.sleep(1);).
When reasoning about thread-safety problems, it may well be that it works on your machine. Or on many machines, under normal conditions. But it does not mean that the program works correctly. Actually, code that "always" worked may break under certain conditions.
Two things here -
Single threaded model - To get value 999999 for sure, you should restrict threads accessing it simultaneously. In this case its main thread and the one being started. you can synchronize the class - synchronized(b.class) as suggested in earlier answer.
Multi threaded model - as you only instance of the class being synchronized class level resources are still accessible simultaneously. In this output guaranteed to be same always.
You are missing the fact that you cannot prove your code is deterministic by running it a bunch of times. You can prove is it not deterministic, however. That is the problem with writing multi-threaded code: it's too easy to misinterpret results according to personal bias. We all do it.
There is something else going on here: the code calls runLoop() indirectly via the start method, which is correct, and the code calls runLoop() directly in the main method. That is why the code isn't deterministic -- that's the answer to the original question. The explicit call to runLoop() in the main method shouldn't be there. All the main should be doing is kicking off the thread.

How Thread works in java?

I have written this code in Java but I can't understand why the output isn't what I expect.
Can anyone explain why Apples and Oranges are cluttered and they are not listed one by one?
package first_experiment;
class Orange extends Thread{
public void run (){
for ( int i=1 ; i<21 ; i++)
System.out.println( i + " - Orange");
}
}
class Apple extends Thread{
public void run(){
for (int i =1 ; i <11 ; i++)
System.out.println( i + " - Apple");
}
}
public class one{
public static void main (String args[]){
Thread O = new Orange();
Thread A = new Apple();
O.start();
A.start();
}
}
The two threads run at the same time. It's up to the JVM to decide which order they get printed out in, and you cannot rely on the order being predictable.
You are creating 2 threads that run concurrently. The order of execution is unknown (since both have the same priority). Note that if PrintStream#println() is not synchronized then the output would be something like:
12 - - A ppOranlgee
// and so on
If you want the results to appear in a particular order, use one thread in a loop.
If you use multiple threads you want them to start and run in any order as much as possible.
Your threads are so short lived, they are running to completion before the other one can start.
BTW: You PC can perform 100,000,000 operations in the time it takes you to blink, and starting a new thread takes time.
Threads run as seperate and indipendant streams of execution. You might loop through several Apples before the first Orange gets some CPU time. Also, if you are on a multiprocessor system, it is possible for both to be running concurently.
If you want them to coordinate their output, you would need to use wait() and notify().
Threads in java are processes running independently when started, one line of started thread code is executed a time with no specific order of execution between threads.
The above code will display in console count - Orange and count - Apple randomly.
The threads may start in any order but the results will be cluttered because System.out.println synchronizes the Thread access to it and as such then are executed one after another for printing.
To see truly random output, save the data in a List and then later print the contents of the List.

Decrease max stacksize at runtime in Java

I'm attempting to write a junit test to guard against a piece of code getting stuck in a endless iteration which will eventually cause a StackOverflow.
so i'm looking for a way to decrease the stack size at runtime so the Junittest will fail faster.
setting the max stack as a jvm argument is not possible because the test is part of a much larger test suite.
You could run a recursive method which will run itself a given number of times and then execute a given action. Sounds pretty flaky though :(
Something like:
public void eatStackThenExecute(int depth, Runnable action)
{
// Maybe put some locals here (and use them) to eat more stack per iteration?
if (depth == 0)
{
action();
}
else
{
eatStackThenExecute(depth - 1, action);
}
}
EDIT: It's possible that smart JVMs will optimise the tail call here, so it may be that we'd need to do "something" after the recursive call to stop that from happening...
Ick 'n stuff :(
It's not possible to set the stack size at runtime, but perhaps you can:
invoke that piece of code inside a different thread - retaining the reference to it;
periodically poll thread.getStackTrace() and fail if its size is larger than x;
cancel the check if execution terminates correctly.
not-compiled proof of concept code ( does not properly check all edge conditions ):
AtomicBoolean success = new AtomicBoolean(false);
Thread t= new Thread(new Runnable() {
public void run() {
codeToTest();
success.set(true);
}
});
t.start();
while ( t.isAlive() ) {
if ( t.getStackTrace().length > 50 )
fail("Stack trace too large");
Thread.sleep(50);
}
assertTrue(sucess.get());
You can only set parameters like this at startup, however you can start another process from Java. So you could make your unit tests start a second process with a smaller stack size to perform your test.
This gets a bit... well, interesting... but it might be worth it.
Take your .class file and decompile it with jasper.
Edit the resulting JVM assembly-esque code and add or alter the ".limit stack x" argument for the routine you want to test in this manner.
Recompile with Jasmin.
Run it and test.

Categories