java Multithreading concurrency of two or more threads? - java

Well,
I'm trying to understand this case. When i create two thread sharing the same instance of Runnable. Why is this order?
Hello from Thread t 0
Hello from Thread u 1
Hello from Thread t 2
Hello from Thread t 4
Hello from Thread u 3 <----| this is not in order
Hello from Thread u 6
Hello from Thread t 5 <----| this one too
Hello from Thread t 8
Hello from Thread t 9
Hello from Thread t 10
i'll show you the code of two thread:
public class MyThreads {
public static void main(String[] args) {
HelloRunnerShared r = new HelloRunnerShared();
Thread t = new Thread(r,"Thread t");
Thread u = new Thread(r,"Thread u");
t.start();
u.start();
}
}
And concluding, the final question is if i'm running this thread i understand they're not running in order but. Why a thread is keeping or printing a number in disorder?
This is the code for the runnable:
class HelloRunnerShared implements Runnable{
int i=0;
public void run(){
String name = Thread.currentThread().getName();
while (i< 300) {
System.out.println("Hello from " + name + " " + i++);
}
}
}
i thought they would be processed intercalated. It's just an assumption!!
Thanks!

Why do you think threads should be executing in a particular order? It's a nondeterministic phenomenon -- whichever is scheduled first, runs first.
Use the ExecutorService.invokeAll if you want things to run in the order in a fixed order, regardless of their schedule.

There are several things going on:
The OS scheduler can switch between threads any time it wants. There's no fairness requirement, the scheduler may favor one thread over another (for instance, it could be trying to minimize the amount of context-switching).
The only locking going on is on the PrintStream used by the println method, which keeps the threads from writing to the console simultaneously. Which thread acquires the lock on the PrintStream when depends on the OS scheduler. The locks used are the intrinsic ones used with the synchronized keyword, they are not fair. The scheduler can give the lock to the same thread that took it last time.
++ is not an atomic operation. The two threads can get in each other's way updating i. You could use AtomicInteger instead of an int.
Access to i is not protected by a lock or any other means of enforcing a happens-before boundary, so updates to it may or may not be visible to other threads. Just because one thread updates i doesn't automatically mean the other thread will see the updated value right away, or at all (how forgiving the JVM is about this depends on the implementation). In the absence of happens-before boundaries the JVM can make optimizations like reordering bytecodes or performing aggressive caching.

Related

Try to solving race condition without using any library in Java

I searched "java race condition" and saw a lot of articles, but none of them is what I am looking for.
I am trying to solve the race condition without using lock, synchronization, Thread.sleep something else. My code is here:
public class Test {
static public int amount = 0;
static public boolean x = false;
public static void main(String[] args) {
Thread a = new myThread1();
Thread b = new myThread2();
b.start();
a.start();
}
}
class myThread1 extends Thread {
public void run() {
for (int i = 0; i < 1000000; i++) {
if (i % 100000 == 0) {
System.out.println(i);
}
}
while(true){
Test.x = true;
}
}
}
class myThread2 extends Thread {
public void run() {
System.out.println("Thread 2: waiting...");
while (!Test.x) {
}
System.out.println("Thread 2: finish waiting!");
}
}
I expect the output should be:
Thread 2: waiting...
0
100000
200000
300000
400000
500000
600000
700000
800000
900000
Thread 2: finish waiting!
(Terminated normally)
But it actually is:
Thread 2: waiting...
0
100000
200000
300000
400000
500000
600000
700000
800000
900000
(And the program won't terminate)
After I added a statement to myThread2, changed
while (!Test.x) {
}
to
while (!Test.x) {
System.out.println(".");
}
The program terminate normally and the output is what I expected (except those ".')
I know when 2 threads execute concurrently, the CPU may arbitrarily switch to another before fetch the next instruction of machine code.
I thought it will be fine if one thread read a variable while another thread write to the variable. And I really don't get it why the program will not terminate normally. I also tried to add a Thread sleep statement inside the while loop of myThread1, but the program still will not terminate.
This question puzzled me few weeks, hope any one can help me please.
Try to declare x as volatile :
static public volatile boolean x = false;
Test.x isn't volatile and thus might not be synchronized between threads.
How the print-command in the second loop affects the overall behavior can't be predicted, but apparently in this case it causes x to be synchronized.
In general: if you omit all thread-related features of java, you can't produce any code, that has a well defined behavior. The minimum would be mark variables that are used by different threads as volatile and synchronize pieces of code, that my not run concurrently.
The shared variable x is being read and written from multiple threads without any synchronisation and hence only bad things can happen.
When you have the following,
while (!Test.x) {
}
The compiler might optimise this into an infinite loop since x (the non volatile variable) is not being changed inside the while loop, and this would prevent the program from terminating.
Adding a print statement will add more visibility since it has a synchronised block protecting System.out, this will lead into crossing the memory barrier and getting a fresh copy of Test.x.
You CAN NOT synchronise shared mutable state without using synchronisation constructs.
Much more better would be a LOCK object you may wait in Thread2 and send a notificytion in thread 1. You are currently active waiting in Thread2 and consume a lot of CPU resources.
Dummy code example:
main() {
Object lock = new Object();
Thread2 t2 = new Thread2(lock);
t2.start();
Thread1 t1 = new Thread1(lock);
t1.start();
...
}
class Thread1 {
Object lock = null;
public Thread1(Object lock) {
this.lock = lock;
...
}
public void run() {
...
synchronized (lock) {
lock.notifyAll();
}
}
} // end class Thread1
// similar Thread2
class Thread2 {
... constructor
public void run()
{
System.out.println("Thread 2: waiting...");
synchronized(lock) {
lock.wait();
}
System.out.println("Thread 2: finish waiting!");
}
....
This construct does not consume any CPU cycles without doing anything in "Thread2". You can create a custom number of "Thread2" instances and wait till "Thread1" is finished. You should "only" start all "Thread2" instances before "Thread1". Otherwise "Thread1" may finish before "Thread2" instances are started.
What you are really asking is, "Why does my program work as expected when I add a call to println()?"
Actions performed by one thread aren't generally required to be visible to other threads. The JVM is free to treat each thread as if it's operating in its own, private universe, which is often faster than trying to keep all other threads updated with events in that private universe.
If you have a need for some threads to stay up-to-date with some actions of another thread, you must "synchronize-with" those threads. If you don't, there's no guarantee threads will ever observe the actions of another.
Solving a race condition without a memory barrier is a nonsensical question. There's no answer, and no reason to look for one. Declare x to be a volatile field!
When you call System.out.println(), you are invoking a synchronized method, which, like volatile, acts as a memory barrier to synchronize with other threads. It appears to be sufficient in this case, but in general, even this is not enough to guarantee your program will work as expected. To guarantee the desired behavior, the first thread should acquire and release the same lock, System.out, after setting x to true.
Update:
Eric asks, "I am curious how volatile work, what has it done behind. I thought that everything can be created by addition, subtraction, compare, jumping, and assignment."
Volatile writes work by ensuring that values are written to a location that is accessible to all reading threads, like main memory, instead of something like a processor register or a data cache line.
Volatile reads work by ensuring that values are read from that shared location, instead of, for example, using a value cached in a register.
When Java byte codes are executed, they are translated to native instructions specific to the executing processor. The instructions necessary to make volatile work will vary, but the specification of the Java platform require that whatever the implementation, certain guarantees about visibility are met.

Java - How is processing time split between threads?

I'm new to threading in Java. I've been reading some online tutorials, but haven't found much material that addresses how the processing time is split between threads.
I created a Runnable class:
public class HelloThread implements Runnable {
public void run() {
int i = 0;
while(true)
{
System.out.println("New Thread" + i);
i++;
}
}
}
and I start the new thread in:
public static void main (String[] args) {
// Start a new thread
Thread helloThread = new Thread(new HelloThread());
helloThread.start();
int i = 0;
while(true)
{
System.out.println("hello from main thread" + i);
i++;
}
}
The output alternates between the message in the helloThread and in the main thread. How is the processing time split between these two threads? I played around with the setPriority() method, but even when I set the helloThread to a priority of 10, the main thread still gets some processing time.
Thanks!
You cannot predict when a thread will run (as you assume). Even if your thread priority is 10, it is no guarantee that you threads will run at all. Threading depends on the concrete JVM (there are different JVM implementation) as well as on the underlying operating system and even on your hardware (like how many cores you have).
In your example, you have two threads (the main thread and your HelloThread). Both are running. So it is a completely OK that both threads run and print messages. It is the purpose of threads to be scheduled alternating and run in parallel.
It is because they have the same priority. You can add statement like
System.out.println( Thread.currentThread().getPriority() );
Both threads should have priority of 5 based on your example
As Thomas Uhrig explained, even with higher priority, the other thread will still get scheduled and executed. It is nondeterministic.

Memory Consistency - happens-before relationship in Java [duplicate]

This question already has answers here:
How to understand happens-before consistent
(5 answers)
Closed 4 years ago.
While reading Java docs on Memory Consistency errors. I find points related to two actions that creates happen - before relationship:
When a statement invokes Thread.start(), every statement that has a
happens-before relationship with that statement also has a
happens-before relationship with every statement executed by the new
thread. The effects of the code that led up to the creation of the
new thread are visible to the new thread.
When a thread terminates and causes a Thread.join() in another thread
to return, then all the statements executed by the terminated
thread have a happens-before relationship with all the statements
following the successful join. The effects of the code in the thread
are now visible to the thread that performed the join.
I am not able to understand their meaning. It would be great if someone explain it with a simple example.
Modern CPUs don't always write data to memory in the order it was updated, for example if you run the pseudo code (assuming variables are always stored to memory here for simplicity);
a = 1
b = a + 1
...the CPU may very well write b to memory before it writes a to memory. This isn't really a problem as long as you run things in a single thread, since the thread running the code above will never see the old value of either variable once the assignments have been made.
Multi threading is another matter, you'd think the following code would let another thread pick up the value of your heavy computation;
a = heavy_computation()
b = DONE
...the other thread doing...
repeat while b != DONE
nothing
result = a
The problem though is that the done flag may be set in memory before the result is stored to memory, so the other thread may pick up the value of memory address a before the computation result is written to memory.
The same problem would - if Thread.start and Thread.join didn't have a "happens before" guarantee - give you problems with code like;
a = 1
Thread.start newthread
...
newthread:
do_computation(a)
...since a may not have a value stored to memory when the thread starts.
Since you almost always want the new thread to be able to use data you initialized before starting it, Thread.start has a "happens before" guarantee, that is, data that has been updated before calling Thread.start is guaranteed to be available to the new thread. The same thing goes for Thread.join where data written by the new thread is guaranteed to be visible to the thread that joins it after termination.
It just makes threading much easier.
Consider this:
static int x = 0;
public static void main(String[] args) {
x = 1;
Thread t = new Thread() {
public void run() {
int y = x;
};
};
t.start();
}
The main thread has changed field x. Java memory model does not guarantee that this change will be visible to other threads if they are not synchronized with the main thread. But thread t will see this change because the main thread called t.start() and JLS guarantees that calling t.start() makes the change to x visible in t.run() so y is guaranteed to be assigned 1.
The same concerns Thread.join();
Thread visibility problems may occur in a code that isn't properly synchronized according to the java memory model. Due to compiler & hardware optimizations, writes by one thread aren't always visible by reads of another thread. The Java Memory Model is a formal model that makes the rules of "properly synchronized" clear, so that programmers can avoid thread visibility problems.
Happens-before is a relation defined in that model, and it refers to specific executions. A write W that is proven to be happens-before a read R is guaranteed to be visible by that read, assuming that there's no other interfering write (i.e. one with no happens-before relation with the read, or one happening between them according to that relation).
The simplest kind of happens-before relation happens between actions in the same thread. A write W to V in thread P happens-before a read R of V in the same thread, assuming that W comes before R according to the program order.
The text you are referring to states that thread.start() and thread.join() also guarantee happens-before relationship. Any action that happens-before thread.start() also happens before any action within that thread. Similarly, actions within the thread happen before any actions that appear after thread.join().
What's the practical meaning of that? If for example you start a thread and wait for it to terminate in a non-safe manner (e.g. a sleep for a long time, or testing some non-synchronized flag), then when you'll try reading the data modifications done by the thread, you may see them partially, thus having the risk of data inconsistencies. The join() method acts as a barrier that guarantees that any piece of data published by the thread is visible completely and consistently by the other thread.
According to oracle document, they define that The happens-before relationship is simply a guarantee that memory writes by one specific statement are visible to another specific statement.
package happen.before;
public class HappenBeforeRelationship {
private static int counter = 0;
private static void threadPrintMessage(String msg){
System.out.printf("[Thread %s] %s\n", Thread.currentThread().getName(), msg);
}
public static void main(String[] args) {
threadPrintMessage("Increase counter: " + ++counter);
Thread t = new Thread(new CounterRunnable());
t.start();
try {
t.join();
} catch (InterruptedException e) {
threadPrintMessage("Counter is interrupted");
}
threadPrintMessage("Finish count: " + counter);
}
private static class CounterRunnable implements Runnable {
#Override
public void run() {
threadPrintMessage("start count: " + counter);
counter++;
threadPrintMessage("stop count: " + counter);
}
}
}
Output will be:
[Thread main] Increase counter: 1
[Thread Thread-0] start count: 1
[Thread Thread-0] stop count: 2
[Thread main] Finish count: 2
Have a look output, line [Thread Thread-0] start count: 1 shows that all counter changes before invocation of Thread.start() are visible in Thread's body.
And line [Thread main] Finish count: 2 indicates that all changes in Thread's body are visible to main thread that calls Thread.join().
Hope it can help you clearly.

Java Thread: explain why not always print the newest value of variable

I have this piece of code using Java Thread:
public class ThreadExample implements Runnable{
public Thread thread;
static int i = 0;
ThreadExample(){
thread = new Thread(this);
thread.start();
}
public static void main(String[] args) {
ThreadExample example = new ThreadExample();
for(int n =0; n<1000; n++){
System.out.println("main thread "+i);
i++;
}
}
public void run(){
for(int index=0; index<1000; index++){
System.out.println("Sub thread "+i);
i++;
}
}
}
And when run, the result is:
main thread 0
Sub thread 0
Sub thread 2
Sub thread 3
Sub thread 4
Sub thread 5
Sub thread 6
Sub thread 7
Sub thread 8
Sub thread 9
Sub thread 10
Sub thread 11
Sub thread 12
main thread 1
....
I know thread that run don't follow by its order. But, the thing that I don't understand is: why main thread prints 1 (it prints variable i), when variable i has come to 12 ? (because subthread has printed to 12).
Thanks :)
Most likely, the explanation is that there's a large delay between when the text is prepared to be printed and when it can actually be printed. The main thread prepared the statement "main thread 1" and then had to wait until the sub thread released the lock on System.out, and it acquired the lock, in order to actually print it.
If you make i volatile, and it still happens, then this is pretty much the only explanation.
This happens because the threads won't see each others modifications without some synchronization or volatile keyword.
See http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1.4
The result is likely due to the way the lock acquisition (which occurs under the covers for the System.out.println call) isn't inherently fair. Unfair implementations, or at least partially unfair ones, usually don't guarantee that the threads will acquire the lock in the same order they wait for it.
The result is that when two threads are competing for the lock repeatedly in a tight loop (as in your example), you will usually have a run of acquisitions by one threads, then a run of acquisitions by the other, and so on. Unfair locks often are simpler to implement, and generally improve performance (throughput) over the perfectly fair alternative for highly contended locks, since they don't suffer from the lock convoy effect. The downside, evidently, is that no guarantees are made about the order particular waiting threads will acquire the lock, and in theory some waiting threads can be starved out in definitely (in practive this may not occur, or the lock may be designed with a fallback to fair behavior when some threads has been waiting an unusual amount of time).
Given unfair locks, the pattern about is natural. The loop in your 2nd thread got the lock, and shortly after the first thread read 1 and began waiting - the String to output has already been concatenated with the leading text at this point, so the value 1 is "baked in". The main thread has to wait for several lock/unlock pairs on the other thread, at which it gets a chance to run, and prints the old value.
An alternate explanation is that due to the lack of volatile, the interpreter or JIT isn't even reading the shared value of i anymore, but has hosted the variable into a register - this is allowed under the JMM and JVM spec since there are no intervening methods which might modify i.
As far as I know this is because of the buffering of System.out
Try to write in a file or call System.out.flush() after each printlen.
and try to increase i via a synchronized method:
public synchronized void increment() {
i++;
}

Do threads work with respect to their respective priority number?

Why would the compiler print 2 a and then 2 b or vice versa when giving the priority to Thread a to start? Shouldn't thread b wait for thread a to finish in order to start? Can someone please explain how does it work?
public class Test1 extends Thread{
static int x = 0;
String name;
Test1(String n) {
name = n;
}
public void increment() {
x = x+1;
System.out.println(x + " " + name);
}
public void run() {
this.increment();
}
}
public class Main {
public static void main(String args[]) {
Test1 a = new Test1("a");
Test1 b = new Test1("b");
a.setPriority(3);
b.setPriority(2);
a.start();
b.start();
}
}
Giving priorities is not a job for the compiler. It is the OS scheduler to schedule and give CPU time (called quantum) to threads.
The scheduler further tries to run as much threads at once as possible, based on the available number of CPUs. In today's multicore systems, more often than not more than one core are available.
If you want for a thread to wait for another one, use some synchronizing mechanism.
Shouldn't thread b wait for thread a to finish in order to start?
No. The priority does not block the thread execution. It only tells the JVM to execute the thread "in preference to threads with lower priority". This does imply a wait.
Since your code is so trivial, there is nothing to wait for. Any of the two threads is run.
Why would the compiler print 2 a and then 2 b?
Luck of the draw. "Priority" means different things on different operating systems, but in general, it's always part of how the OS decides which thread gets to run and which one must wait when there's not enough CPUs available to run them both at the same time. If you computer has two or more idle CPUs when you start that program, then everybody gets to run. Priority doesn't matter in that case, and its just a race to see which one gets to the println(...) call first.
The a thread in your example has an advantage because the program doesn't call b.start() until after the a.start() method returns, but how big that advantage actually is depends on the details of the OS thread scheduling algorithm. The a thread could get a huge head start (like, it actually finishes before b even starts), or it could be a near-trivial head start.

Categories

Resources