A simple Java Race Condition - java

I just wanted to write an example for an race condition:
MyParallelClass.java:
public class MyParallelClass implements java.lang.Runnable {
public int counter = 0;
#Override
public void run() {
if (test.globalVar > 0) {
for (int i = 0; i < 1000000; i++) {
counter++;
}
test.globalVar--;
}
}
}
test.java:
public class test {
public static int globalVar;
public static void main(String[] args) {
globalVar = 1;
MyParallelClass a = new MyParallelClass();
MyParallelClass b = new MyParallelClass();
new Thread(a).start(); // Thread A
new Thread(b).start(); // Thread B
System.out.println(globalVar);
}
}
What I thought would happen:
I thought this could output either 0 if thread A was executed completely before Thread B starts.
The variable test.globalVar could also get manipulated like this:
Thread A - Thread B
checks if (globalVar > 0)
looping ... checks if (globalVar > 0)
looping ... execute all four bytecode commands of "test.globalVar--;"
execute test.globalVar--;
so the value of test.globalVar would be -1.
So either one of the if-statements get executed or both.
What actually happened:
I got 0 and 1 as output of the main method. Why do I get 0 and 1 and not 0 and -1?

You are decrementing globalVar twice. The possible values of globalVar at the end are:
-1 - if everything went fine and both threads correctly decremented the value before it was printed
0:
if only one thread managed to decrement the variable and the second one didn't manage to finish before printing it
if the globalVar was decremented at the same time
1:
if System.out.println() managed to execute before both threads completed (quite probable). The globalVar was indeed modified, but after it was already printed
due to visibility issue main thread sees original globalVar value, not the one modified by different threads. You need some sort of synchronization or volatile keyword to see changes made by other threads immediately (or ever).

The
System.out.println(globalVar);
does not wait for the threads to complete. The threads may or may not be complete at that point. So the value can be 0, 1, or -1 depending on whether both the threads completed, one completed or both did not complete.
To have a better test,
- use Thread.sleep() in the threads to make sure that there is a delay
- Use different delays in the different threads to better visualize the race condition.
- You may want to print the value of the variable in the threads also. this way you have three threads racing (A, B and the main thread) and you get better visualizations.

Good question. I think you need to run more tests. :-)
You might try changing your loop in the Runnable class to sleep with a random number of milliseconds (500-1000). Loop just 10 times. See if you don't get your expected race condition.
I think that most computers are just too darn fast. You're simple loop may not be doing enough work to cause a thread switch.
I love these kinds of questions because I run into bugs like this all the time.

You can get a 1 if the value is printed before either thread has decremented the value.

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;

Java - Thread and Static variable

Just started with threads in java and I can't reason with the output of my program
public class ThreadExample extends Thread{
private int info;
static int x = 0;
public ThreadExample (int info) {
this.info = info;
}
public void run () {
if ( info == 1 ) {
x = 3;
System.out.println(Thread.currentThread().getName() + " " + x);
} else{
x = 1;
System.out.println(Thread.currentThread().getName() + " " + x);
}
}
public static void main (String args []) {
ThreadExample aT1 = new ThreadExample(1);
ThreadExample aT2 = new ThreadExample(2);
aT1.start();
aT2.start();
System.err.println(x);
}
}
Output:
Thread-0 3
Thread-1 1
3
Why does it print 3 even though the 2nd thread changed the value of the static variable to 1?
Will there be 3 threads running concurrently?
If you change a variable in one thread it not immediately (or necessary ever) visible to a 2nd thread unless you use some kind of synchronization primitive like a Mutex. You can also use the atomic classes like AtomicInteger to ensure changes made in one thread become visible to the other.
There's a lot more information available in the documentation.
Two possible scenarios
Thread 2 would have updated x before Thread 1. You cannot determine how the execution interleaved between the two threads based on the order of the print statements you are seeing.
The threads indeed executed in the order you expect. But since x is not volatile you might not see the updated value.
See - What is the volatile keyword useful for
You cannot predict the result of threading.
It may be different if you run your code on another device or just multiple times.
You cannot (or should not) rely on timing or the scheduler.
I think that concurrency/non-volatility itself may not be the only problem but flushing is also something you may want to take into consideration:
x=3 (ThreadExample(1))
sysout 3 (ThreadExample(1))
syserr x (main thread)
x=1 (ThreadExample(2))
sysout 3 (ThreadExample (2))
flush stdout (caused by jvm exit)
flush stderr (caused by jvm exit)
Note the flush at the end. stdout and stderr may not be synchronized.
Those streams are buffered and written to the console at any time.
While two things written to stdout or stderr are guaranteed to be written in the correct order, this is not assured if you pring one thing to stdout and another thing to stderr.
It is also guaranteed that everything printed to stdout and stderr is written when the jvm terminates normally(no kill -9 or similar).
If the jvm writes stdout before stderr, you can get your result.
If you want the output to be printed correctly, you may want to do two things:
Call flush manually after printing
create a synchronized block(or similar) around the operation, the println and the flush. (Note that you may lose a bit of performance/parallelism with that)
If you want to test if flushing makes a difference in your case, add System.err.flush(); (so that stderr is flushed before stdout)at the end of your profram and see if there is a difference.
Also, there obe more thing that I didn't find in other answers, explicitly: JIT optimization.
The JIT compiler may make optimizations to your program. For example, it could optimize:
x=3;
System.out.println(x);
to:
x=3;
System.out.println(3);
so that it prints 3, even if it is not 3 at the time the println is called.
Variables are not recommended way to exchange information between threads. Use BlockingQueues for messages, Semaphores and CountDownLatches for signals. In short, transfer of a value must not only make silent assignment, but also create some kind of event, to notify other threads. I like word "token" for such objects.
Will there be 3 threads running concurrently?
Yes. The first thread is the main thread, the one which started it all, the one which invoked your public static void main (String args []) method. All code runs on a thread. Your main method then starts 2 threads. Since you started with 1, you now have 3.
As for why the final output from the main thread is 3 is hard to answer because you have a race condition. You have 3 threads reading a variable while 2 of them update, and these all happen concurrently.
x = 3;
System.out.println(Thread.currentThread().getName() + " " + x);
With 3 threads running, it's easy to assume the output of System.out.println above will be 3, but the reality is, after setting it to 3, another thread could have updated it and then when you print it, it's no longer 3.
Also consider the volatile keyword. Without it, the JVM may cache within a thread copies of shared values, which can lead to staleness when reading and writing across threads. What is the volatile keyword useful for
The outcome of threads is unpredictable.
To ensure consistent/predictable behavior use volatile/Atomic values to make the change visible to other threads

How does "Compare And Set" in AtomicInteger works

AtomicInteger works with two concepts : CAS and volatile variable.
Using volatile variable insures that the current value will be visible to all threads and it will not be cached.
But I am confused over CAS(compare AND set) concept which is explained below:
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
My question is that whatif(compareAndSet(current, next) returns false? Will the value not be updated?
In this case what will happen when a Thread is executing the below case:
private AtomicInteger count = new AtomicInteger();
count.incrementAndGet();
The atomic objects make use of Compare and Swap mechanism to make them atomic - i.e. it is possible to guarantee that the value was as specified and is now at the new value.
The code you posted continually tries to set the current value to one more than it was before. Remember that another thread could also have performed a get and is trying to set it too. If two threads race each other to change the value it is possible for one of the increments to fail.
Consider the following scenario:
Thread 1 calls get and gets the value 1.
Thread 1 calculates next to be 2.
Thread 2 calls get and gets the value 1.
Thread 2 calculates next to be 2.
Both threads try to write the value.
Now because of atomics - only one thread will succeed, the other will recieve false from the compareAndSet and go around again.
If this mechanism was not used it would be quite possible for both threads to increment the value resulting in only one increment actually being done.
The confusing infinite loop for(;;) will only really loop if many threads are writing to the variable at the same time. Under very heavy load it may loop around several times but it should complete quite quickly.
for (;;) is an infinite loop, so it will just retry the attempt.

Looping in Threads

Consider the following two designs of run method:
Approach A
public void run() {
do {
//do something
} while (condition);
}
Approach B
public void run() {
//do something...
if (condition) {
new Thread(this).start();
}
}
The second approach seems cleaner to me, after some debate, I have been told it's not a good idea to use approach two.
Question:
What are reasons (if there is any) that I shouldn't be using approach 2?
You have two things here. A loop, and a method that continuously runs itself again in a new thread until a condition is met (not a loop).
If you need a loop, you would choose the standard normal loop that everyone understands and works perfectly.
If you need to write a weird piece of code that creates new threads for no reason, and makes other developers doubt your skills and understanding, you would go for option B.
There's absolutely no sense in your choice B unless there would be something additional like a queue or ThreadPoolExecutor involved for re-invoking the method, so the method would add this at the end for invocation at a later time, sort of like a "lazy loop".
Because approach B uses one more thread than approach A. Creating threads is expensive, for a number of reasons #see Why is creating a Thread said to be expensive?
Approach A is also a little clearer to the reader, IMO. The simplest option usually is.
The 2nd option creates a new thread every time it is iterated, so it ends up being unnecessarily costly, especially when option A does the same thing but doesn't create new threads for every iteration.
The only good use-case I can find for Pattern B is if there is a significant delay before you want to re-run the method. For example for some kind of polling system that is supposed to run every X minutes until the system is being shut down.
In that case, using a scheduler instead of a Thread.sleep(fiveMinutes) makes sense to avoid tieing up resources unnecessarily (maybe you are holding on to a database connections or such).
Note that in that case, you'd be using a scheduler, not just Thread#start, so I am allowing for a rather liberal interpretation of Pattern B.
They will behave very differently.
The first solution will loop until condition is false and then terminate.
The second solution will start a new thread and die until condition is false. It will likely accomplish what you want to do but it will waste a lot of resources allocating and destroying new threads.
Here's an example that loops over 5 values and prints the value and current thread name:
Loop:
Runnable loop = new Runnable() {
int i = 0;
#Override
public void run() {
do {
System.out.printf("%s: %s%n", Thread.currentThread().getName(), i);
i++;
} while(i < 5);
}
};
loop.run();
main: 0
main: 1
main: 2
main: 3
main: 4
Threaded:
Runnable thread = new Runnable() {
int i = 0;
#Override
public void run() {
System.out.printf("%s: %s%n", Thread.currentThread().getName(), i);
i++;
if(i < 5) {
new Thread(this).start();
}
}
};
thread.run();
main: 0
Thread-0: 1
Thread-1: 2
Thread-2: 3
Thread-3: 4
As you can see, the threaded example prints each line on a different thread which is very wasteful and probably not what you want to accomplish.

Multithreading--Why one thread is doing all of the work?

I am multiplying two matrices using two threads (however, the program is written to scale up as well, so I could possibly use three, four, etc threads instead). Each thread calculates/does the work for one row (or column) of the final matrix. If one thread is doing work on a row, the other one(s) should not work on that row. It/they should move on to the next available row.
First of all, I am not certain if the way I implemented the problem is correct. If you can see a better way, please let me know.
Secondly, the way I have done it, every time I test it (with different size matrices--even huge ones), only one thread does the work. That is, each time, the same thread is getting access to the synchronized block of the run() method. The other threads are entering the run() method, but why is only one thread always gaining the lock and doing all of the work?
This is my run method:
public void run() {
System.out.println(Thread.currentThread().getName());
while (i < number of columns in final matrix) {
synchronized (this) {
if (i < number of columns in final matrix) {
for (int j = 0; j < Main.B[0].length; j++) {
for (int k = 0; k < Main.A[0].length; k++) {
Main.C[i][j] += Main.A[i][k] * Main.B[k][j];
}
}
i++;
}
}
}
}
This is the code in my driver class that creates the threads and starts the program:
MyRunnable r = new MyRunnable();
Thread thread1 = new Thread(r);
Thread thread2 = new Thread(r);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException ie) {
System.out.println("\nThe following error occurred: " + ie);
}
}
I guess my question is two-fold--is my approach correct for the problem at hand? If so, (and if not), why is one thread always grabbing the lock and doing all of the work? I have checked the program with up to 6 threads on 20x20 matrices and always only one thread is doing the work.
As some of the comments suggested, the problem is in the locking (i.e. the synchronized(this) part). Synchronizing is done on this which, in your case, a single instance of MyRunnable, so while one thread is doing the work inside the synchronized block, all other threads will wait until the work is finished. So effectively, only one thread is doing real work at a time.
Here's how to solve the problem. Since you need your threads to work on different rows in parallel, then this work must not be synchronized by a lock (because locking means the opposite: only one thread can do the work at a time). What you do need to synchronize is the part where each thread decides which row it will work on.
Here's a sample pseudo code:
public void run(){
int workRow;
synchronized(this){
workRow = findNextUnprosessedRow();
}
for(int i=0; i<matrix[workRow].length; i++){
//do the work
}
}
Note that the actual work is intentionally not synchronized, for reasons given above.
The way you are using threads is correct, so there is not problem with that, however, I would suggest you have a look at Java's concurrency API: Thread Pools. Here's an example of how to use it in your context:
//Creates a pool of 5 concurrent thread workers
ExecutorService es = Executores.newFixedThreadPool(5);
//List of results for each row computation task
List<Future<Void>> results = new ArrayList<Future<Void>>();
try{
for(int row=0; row<matrix.length; row++){
final int workRow = row;
//The main part. You can submit Callable or Runnable
// tasks to the ExecutorService, and it will run them
// for you in the number of threads you have allocated.
// If you put more than 5 tasks, they will just patiently
// wait for a task to finish and release a thread, then run.
Future<Void> task = es.submit(new Callable<Void>(){
#Override
public Void call(){
for(int col=0; col<matrix[workRow].length; col++){
//do something for each column of workRow
}
return null;
}
});
//Store the work task in the list.
results.add(task);
}
}finally{
//Make sure thread-pool is shutdown and all worker
//threads are released.
es.shutdown();
}
for(Future<Void> task : results){
try{
//This will wait for threads to finish.
// i.e. same as Thread.join()
task.get();
}catch(ExecutionException e){
//One of the tasks threw an exception!
throw new RuntimeException(e);
}
}
This approach is a lot cleaner, because the work distribution is done the main
thread (the outer for-loop), and therefore there is no need to synchronize it.
You also get few bonuses when working with thread pools:
It nicely takes care of any exceptions during the computations in each
of the threads. When working with bare threads, like in your approach, it is easy
to "lose" an exception.
Threads are pooled. That is, they get automatically reused so you don't need to worry about the cost of spawning new threads. This is particularly useful in your case, since you will need to spawn a thread per row in your matrix, which may be fairly large, I suspect.
Tasks submitted to ExecutorService are wrapped in a useful Future<Result> object, which is most useful when each computation task actually returns some kind of result. In your case, if you needed to sum-up all values in the matrix, then each computation task could return the sum for the row. Then you'd just need to sum up those up.
Got a bit long, but hope it clears some things up.
Your problem is that you synchronize the whole region with synchronized(this). This means that only one thread at a time is allowed to enter the loop doing the calculation. Of course it could mean that multiple threads can calculate different parts but never multiple threads at once. This also means your "parallel" solution it is not faster than one thread.
If you want to do the calculation in parallel have a look at Parallel Matrix Multiplication in Java 6 and Fork Join Matrix Multiplication in Java which should cover the topic
Thread scheduling depends on the particular VM implementation. In some implementations a thread will continue to run until it blocks in some way or is preempted by a higher priority thread. In your case all the threads have the same priority, so the first thread to enter the synchronized block never blocks, it does not get preempted. Some schedulers implement priority aging, such that a starved thread will eventually increase in priority, but you may not be running long enough for that to have an effect.
Add a Thread.yield() call just after the end of the synchronized block. This tells the scheduler to pick a new thread to run (maybe the same one, but probably a different one).
Your run function has the first thread to get the lock do all the work on a row while still owning the lock. For the next row, maybe another thread will get the lock, but it will block all other threads until it is done.
What I would do is have an array of booleans that is the same as the number of rows, and use these to claim the task of processing each individual row. It would be something like the following pseudocode:
//before creating the threads, pre-fill BoolList with trues
function run()
{
while (true)
{
lock(BoolList)
{
//find first true value and set it to false
//if no true found, return
}
//do the actual math of multiplying the row we claimed above
}
}
Also keep in mind that the overhead of creating a new thread is sufficient that multi-threading this program would only be worth it for large matrices.
As mru already stated in his comment, you problem is that all row calculation is performed inside "synchronized (this)" block. Because of this all threads will wait for one row to be processed before starting on next one, and same thread always acquiring the lock is probably the result of optimization, since you pretty much make calculations single-thread. You might consider putting only decision on which row to process inside the synchronized block:
int rowToProcess;
synchronized (this) {
if (i < number of columns in final matrix){
rowToProcess = i;
i++;
}
else
return;
}

Categories