How Thread works in java? - 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.

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

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

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.

Why my input is showing one thread executing after another thread, not at the same time?

I researched the concept of a thread and saw that it is to have code run in two processes at the same time. Heres my code though
public class Connor extends Thread{
public void run() {
for(int i=0; i< 10; i ++){
System.out.println("Hello " + i);
}
public static void main(String[] args){
Connor runner1 = new Connor();
Connor runner2 = new Connor();
runner1.start();
runner2.start();
}
}
And my output http://imgur.com/yAZqgal
It seems like the two threads do start off at the same time(separate processes, as indicated by the two leading 0s) but one executes (1-9) and then the other executes (1-9). Arent they suppose to interweave as well (1,1,2,2,...) bc the threads both print to the console. I researched and saw that start is the right method to use as it tells the thread class to execute the run method in another thread? Can anyone explain why im getting this output?
Say you have ten errands you need to do and your sister has ten errands she needs to do, and you only have one car. Do you bring the car back after each errand and switch drivers? Of course not. That would be absurdly inefficient. Each thread basically just needs the output stream. So it would be absurd to interleave them tightly.
Your code looks fine. I guess that your threads do not run in parallel just because they terminate to fast. Change the loop limit from 10 to 1000 and you will see the effect.
Starting thread itself is relatively heavy operation. You code starts the first thread and then the second one. The first thread once started terminates before the second thread got a chance to start executing its business logic.
In case of Multi-threading there is no guarantee that which thread is allocated for what time to run by the processor and in that case the result is unpredictable and will generate different output for each run.
If you are looking for desired output then you need synchronization block. using wait and notify you can achieve it easily.
Please have a look at below Lesson directly from Oracle official site:
Lesson: Concurrency to read more about concurrency.
Chapter 17. Threads and Locks to read more about thread, locks and synchronization.
Note: wait & notify must be called inside the synchronized block and can call on the same object on which it is synchronized.
Sample code: (read inline comments)
public class Connor extends Thread {
private static Connor runner1 = new Connor();
private static Connor runner2 = new Connor();
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Hello " + i);
// wake up another thread to come out from wait state
if (runner1 == this) {
// wake up runner2
synchronized (runner2) {
runner2.notify();
}
} else {
// wake up runner1
synchronized (runner1) {
runner1.notify();
}
}
synchronized (this) {
try {
// say current thread to wait until notify by another thread
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
runner1.start();
runner2.start();
}
}
output:
Hello 0
Hello 0
Hello 1
Hello 1
Hello 2
Hello 2
Hello 3
Hello 3
Hello 4
Hello 4
Hello 5
Hello 5
Hello 6
Hello 6
Hello 7
Hello 7
Hello 8
Hello 8
Hello 9
Hello 9
Why my input is showing one thread executing after another thread, not at the same time?
The general explanation is that Thread scheduling is unpredictable. Interleaving may happen ... or it may not. That is fundamental to Java threading. (And indeed to threading in most other languages.)
If you need thread execution to interleave in an entirely predictable way, you need to implement some kind of hand-shake mechanism, where one thread waits for another one to do something, and do on. But that is complicated, and typically defeats the purpose of using threading.
FWIW: #Braj's answer shows how you might implement strict interleaving. However note that this effectively means that only one thread is going to execute at a time. In addition, the waiting / notifying is going to lead to a lot of work for the thread scheduler ... some that the application will run significantly slower than if you had just done the work on one thread.
In this particular example, there are two issues that combine to make any short term interleaving unlikely:
Creating a new native thread in Java is relatively expensive, because it typically entails requesting a memory block from the OS to house the thread stack. That in turn entails the OS "messing around" with page tables, zeroing a memory block and so on.
Native thread scheduling is implemented by the operating system, and it operates at a fairly coarse-grained level ... because that is the most efficient way to operate from the perspective of a typical application. (Switching thread "contexts" in a PC-class machine is relatively expensive operation, and the thread scheduler itself potentially has work to do.)
In your example, the chances are that the first thread can say "hello" ten times before the second thread is ready to be scheduled.

These three threads don't take turns when using Thread.yield()?

In an effort to practice my rusty Java, I wanted to try a simple multi-threaded shared data example and I came across something that surprised me.
Basically we have a shared AtomicInteger counter between three threads that each take turns incrementing and printing the counter.
main
AtomicInteger counter = new AtomicInteger(0);
CounterThread ct1 = new CounterThread(counter, "A");
CounterThread ct2 = new CounterThread(counter, "B");
CounterThread ct3 = new CounterThread(counter, "C");
ct1.start();
ct2.start();
ct3.start();
CounterThread
public class CounterThread extends Thread
{
private AtomicInteger _count;
private String _id;
public CounterThread(AtomicInteger count, String id)
{
_count = count;
_id = id;
}
public void run()
{
while(_count.get() < 1000)
{
System.out.println(_id + ": " + _count.incrementAndGet());
Thread.yield();
}
}
}
I expected that when each thread executed Thread.yield(), that it would give over execution to another thread to increment _count like this:
A: 1
B: 2
C: 3
A: 4
...
Instead, I got output where A would increment _count 100 times, then pass it off to B. Sometimes all three threads would take turns consistently, but sometimes one thread would dominate for several increments.
Why doesn't Thread.yield() always yield processing over to another thread?
I expected that when each thread executed Thread.yield(), that it would give over execution to another thread to increment _count like this:
In threaded applications that are spinning, predicting the output is extremely hard. You would have to do a lot of work with locks and stuff to get perfect A:1 B:2 C:3 ... type output.
The problem is that everything is a race condition and unpredictable due to hardware, race-conditions, time-slicing randomness, and other factors. For example, when the first thread starts, it may run for a couple of millis before the next thread starts. There would be no one to yield() to. Also, even if it yields, maybe you are on a 4 processor box so there is no reason to pause any other threads at all.
Instead, I got output where A would increment _count 100 times, then pass it off to B. Sometimes all three threads would take turns consistently, but sometimes one thread would dominate for several increments.
Right, in general with this spinning loops, you see bursts of output from a single thread as it gets time slices. This is also confused by the fact that System.out.println(...) is synchronized which affects the timing as well. If it was not doing a synchronized operation, you would see even more bursty output.
Why doesn't Thread.yield() always yield processing over to another thread?
I very rarely use Thread.yield(). It is a hint to the scheduler at best and probably is ignored on some architectures. The idea that it "pauses" the thread is very misleading. It may cause the thread to be put back to the end of the run queue but there is no guarantee that there are any threads waiting so it may keep running as if the yield were removed.
See my answer here for more info : unwanted output in multithreading
Let's read some javadoc, shall we?
A hint to the scheduler that the current thread is willing to yield
its current use of a processor. The scheduler is free to ignore this
hint.
[...]
It is rarely appropriate to use this method. It may be useful
for debugging or testing purposes, where it may help to reproduce bugs
due to race conditions. It may also be useful when designing
concurrency control constructs such as the ones in the
java.util.concurrent.locks package.
You cannot guarantee that another thread will obtain the processor after a yield(). It's up to the scheduler and it seems he/she doesn't want to in your case. You might consider sleep()ing instead, for testing.

Categories