I have a simple snippet of code and try to experiment a little with it, but in the next code I get unclear for me order of output data:
public class Main {
static int n = 100;
public static synchronized int decreaseValue(){
return --n;
}
public static void main(String[] args) throws InterruptedException, IOException {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
while(true){
try {
System.out.println("Thread1: "+ decreaseValue());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"Thread1");
t1.start();
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
while(true){
try {
System.out.println("Thread2: "+ decreaseValue());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"Thread2");
t2.start();
while(true){
try {
System.out.println("Main Thread: "+ decreaseValue());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Can not understand, why I get the such values in the next order:
Thread1: 89
Thread2: 90
Main Thread: 88
PLEASE PAY ATTENTION TO THE N VALUE NOT TO THE ORDER OF CALLING THREADS:
Thread1: 99
Thread2: 98
Main Thread: 97
Main Thread: 95
Thread2: 94
Thread1: 96
Main Thread: 92
You must have read somewhere that synchronized must be used to ensure proper ordering, or something similar. The word "ordering" pertains to a different concept from the one you have in mind: it means that there will always be some definite ordering to the execution of synchronized blocks. The ordering is not known in advance, but it will be there every time. Without synchronized, you won't even get that guarantee: one thread could perceive one order, another thread a different order, or not perceive any actions by other threads at all.
About your edit:
If you are concerned about printouts happening out of order, this is because your println statements are outside of synchronized and so can interleave independently of the calls to decreaseValue.
Thread runs in parallelly. You can't predict their execution order. You can set thread priority which prioritize its execution order.
The threads are running concurrently and nothing is imposing the order on wich they should call your decreaseValue() function. You would expect them to be in order since you are doing the same amount of sleep :), but as soon as a thread will start/resume from a sleep, the CPU will place the thread in a running queue (creating an execution order, this is the order that synchronize will guarantee), because of this the order of your printing depends on how the CPU will place the thread in the running queue.
The print on the console is also synchronized (but not in the same block with your decreaseValue), if you are questioning the printing order. The same logic applies to printing as the one to decrease the values.
If you would like to see the prints in the same order that the value was decremented you can move print in the decreaseValue() function. But this will not affect the order in how the values will be decremented.
Related
I know that the synchronize(LOCK) is unfair, which means there is no guarantee that the longest waiting thread will win the lock. However in my little experiment below it seems that the lock was acquired by shortest waiting threads...
public class Demo {
public static final Object LOCK = new Object();
public void unfairDemo(){
// Occupy the lock for 2 sec
new Thread(() -> {
synchronized (LOCK) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
// Spawn 10 new threads, each with 100ms interval, to see which can win the lock
// If lock is fair then it should print the i in asc order
for (var i = 0; i < 10; i++) {
int finalI = i;
new Thread(() -> {
System.out.println("Added " + String.valueOf(finalI) + "th element to wait for lock");
synchronized (LOCK) {
System.out.println("I got the lock, says " + String.valueOf(finalI) + "-th thread");
}
}).start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
// Keep the program alive
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Running unfairDemo() prints the following:
Added 0th element to wait for lock
Added 1th element to wait for lock
Added 2th element to wait for lock
Added 3th element to wait for lock
Added 4th element to wait for lock
Added 5th element to wait for lock
Added 6th element to wait for lock
Added 7th element to wait for lock
Added 8th element to wait for lock
Added 9th element to wait for lock
I got the lock, says 9-th thread
I got the lock, says 8-th thread
I got the lock, says 7-th thread
I got the lock, says 6-th thread
I got the lock, says 5-th thread
I got the lock, says 4-th thread
I got the lock, says 3-th thread
I got the lock, says 2-th thread
I got the lock, says 1-th thread
I got the lock, says 0-th thread
I expected that the order would be scrambled, but no matter how I tried the results are in reverse order. What did I do wrong here?
There are many sources, such as this, that already indicate that there should be no assumption regarding the order in which threads acquire locks. But it doesn't mean the order has to be scrambled.
It probably depends at the very least on the JVM implementation. For example, this document about HotSpot says:
Contended synchronization operations use advanced adaptive spinning techniques to improve throughput even for applications with significant amounts of lock contention. As a result, synchronization performance becomes so fast that it is not a significant performance issue for the vast majority of real-world programs.
...
In the normal case when there's no contention, the synchronization operation will be completed entirely in the fast-path. If, however, we need to block or wake a thread (in monitorenter or monitorexit, respectively), the fast-path code will call into the slow-path. The slow-path implementation is in native C++ code while the fast-path is emitted by the JITs.
I'm not an expert on HotSpot (maybe someone else can provide a more authoritative answer), but based on the C++ code, it looks like the contending threads will be pushed onto a LIFO structure, which may explain the stack-like order you observed:
// * Contending threads "push" themselves onto the cxq with CAS
// and then spin/park.
...
// Cxq points to the set of Recently Arrived Threads attempting entry.
// Because we push threads onto _cxq with CAS, the RATs must take the form of
// a singly-linked LIFO.
What did I do wrong here?
You do all right.
Your expirement shows program execution order in this particular case. Java do not guarantee any order of threads execution without special efforts from programmer's side.
Try this to see chaos:
public class Demo {
public static final Object LOCK = new Object();
public void unfairDemo() {
createThread(0).start();
for (var i = 1; i < 5; i++) {
createThread(i).start();
}
}
private static Thread createThread(final int number) {
return new Thread(() -> {
System.out.println("Added " + number + "th element to wait for lock");
synchronized (LOCK) {
System.out.println("I got the lock, says " + number + "-th thread");
try {
Thread.sleep(number == 0 ? 2000 : 100);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
});
}
public static void main(String[] args) {
new Demo().unfairDemo();
}
}
Look at this code:
public class VolatileTest {
private static boolean ready = false;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(){
#Override
public void run() {
ready = true;
System.out.println("t2 thread should stop!");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t2 = new Thread(){
#Override
public void run() {
while(!ready){
System.out.println("invoking..");
}
System.out.println("I was finished");
}
};
t1.start();
t2.start();
}
}
I think the result of this code maybe:
t2 thread should stop!
invoking..
I was finished
because of in the multithreading, when the t1 modify 'ready' variable to true,then I made t1 sleep. At the moment, I think, to t2 the 'ready' variable is false!!! because t1 thread is not stop, the variable in t1 is invisible in t2.
But in fact.. I test many times. the result is always this:
Am my idea is wrong?
First of all, despite calling your class VolatileTest, you are not actually using volatile anywhere in your code.
Since the ready variable is not declared as volatile AND you are accessing it without any explicit synchronization, the behavior is not specified. Specifically, the JLS does not say whether the assignment made in thread 1 to the ready variable will be visible within thread 2.
Indeed, there is not even guaranteed that the run() method for thread 1 will be called before the run() method for thread 2.
Now it seems that your code (as written!) is behaving in a way that is consistent with the write of true always being visible immediately. However, there is no guarantee that that "always" is actually always, or that this will be the case on every Java platform.
I would not be surprised if the syscall associated with sleep is triggering memory cache flushing before the second thread is scheduled. That would be sufficient to cause consistent behavior. Moreover, there is likely to be serendipitous synchronization1 due to the println calls. However, these are not effects you should ever rely on.
1 - Somewhere in the output stream stack for System.out, the println call is likely to synchronize on the stream's shared data structures. Depending on the ordering of the events, this can have the effect of inserting a happens before relationship between the write and read events.
As I mentioned in my comment, there are no guarantees. ("There is no guarantee what value thread t2 will see for ready, because of improper synchronization in your code. It could be true, it could be false. In your case, t2 saw true. That is consistent with "there is no guarantee what value t2 will see")
You can easily get your test to fail by running it multiple times.
When I run below code that does your test 100 times, I always get 14-22 "notReadies", so 14-22% of the cases you will not see the change to ready in Thread t2.
public class NonVolatileTest {
private static boolean ready = false;
private static volatile int notReadies = 0;
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 100; i++) {
ready = false;
// Copy original Thread 1 code from the OP here
Thread t2 = new Thread() {
#Override
public void run() {
if (!ready) {
notReadies++;
}
while (!ready) {
System.out.println("invoking..");
}
System.out.println("I was finished");
}
};
t1.start();
t2.start();
// To reduce total test run time, reduce the sleep in t1 to a
// more suitable value like "100" instead of "5000".
t1.join();
t2.join();
}
System.out.println("Notreadies: " + notReadies);
}
}
I am new to multithreading. I am trying to write a program where I have two threads. One thread prints odd number and then gives up the monitor lock using wait() and similarly other thread prints the even number and gives up the lock after printing the number
I have got 4 classes
Odd.java (print odd numbers between 1-100)
Even.java(print even number between 1-100)
SomeMaths.java( has got logic for printing odd and even numbers )
OEApp.java (Main class that starts the threads)
Problem - My code works as expected most of the times i.e it print number 1 to 100 in order. Both the thread take turns. But I noticed that there is a bug.Sometimes the even thread gets scheduled first and gets below output
2 **********
1 ###############################
After that nothing gets printed, Looks like there is a deadlock situation. I am not able to figure out why. Please help me to understand this
public class SomeMaths {
public synchronized void printOdd(){
for( int i=1;i<=100;i++){
if(i%2 !=0) {
System.out.println(i + " ###############################");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
}
}
public synchronized void printEven(){
for(int i=1;i<=100;i++){
if(i%2 ==0){
System.out.println(i +" **********");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
}
}
}
public class Odd implements Runnable {
SomeMaths sm;
public Odd(SomeMaths sm){
this.sm = sm;
}
#Override
public void run(){
sm.printOdd();
}
}
public class Even extends Thread {
SomeMaths sm;
public Even(SomeMaths sm){
this.sm = sm;
}
#Override
public void run(){
sm.printEven();
}
}
public class OEApp {
public static void main(String[] args) {
SomeMaths sm = new SomeMaths();
Thread odd = new Thread(new Odd(sm));
Thread even = new Thread(new Even(sm));
odd.start();
even.start();
try {
odd.join();
even.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I believe it works this way:
Even thread starts, 1 is odd so it calls notify (notifying no one), then 2 is even so it prints a message and waits
Odd thread starts, 1 is odd so it prints a message and waits
There's no one to call notify so both threads wait forever
What is your purpose for using the synchronize keyword ?
It can only assure you that your function will not be running multiple times at the same time.
I assume that you want one thread to notify another ? Is that right ?
But what if the notify is called before the wait occurred ?
You know that you can use the debugger to see each thread, and thus know where each thread is stuck ?
Please keep in mind, once start is called, you can't know which thread will have cpu time.
Furthermore you are trying to synchronize two threads (by the use of the notify/wait mecanism), but there are other mecanisms that will be proved simpler (e.g. semaphore: each thread having it own semaphore, acquiring it own semaphore and releasing the other one semaphore; initialize each semaphore to 1 and it will go smoothly).
P.S. :
I am forced to post an answer, but it should be a comment; sorry
Why use both runnable and thread interface ? Furthermore your Even class is already a thread, so no use to wrap it once again.
See https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem
public abstract class Multithread implements Runnable{
static Thread t1 = new Thread(){
public synchronized void run(){
try {
for(;;){
System.out.println("java");
t1.sleep(300);
}
} catch (Exception e) {
System.out.println("Exception"+e);
}
}
};
static Thread t2 = new Thread(){
public synchronized void run(){
try{
for(;;){
System.out.println("world");
t2.sleep(300);
}
}catch(Exception e){
System.out.println("Exception"+e);
}
}
};
public static void main(String[] args) {
try{
t1.start();
t2.start();
}catch(Exception e){
System.out.println("Exception "+e);
}
}
#Override
public void run() {
System.out.println("running");
}
}
Excepted O/P:
java
world
java
world
java
world
.
.
.
.
observed
I tried using sleep() for the threads,they are getting overlapped at some point of time like this-
java
java
world
java
world
world
java
..
Expected
i need these two threads to run in parallel and it should not get overlapped,either of the thread can be started. Any idea?
Threads are not accurate in time. If they depend on each other, you have to manually synchronize, like : How to execute two threads Sequentially in a class
You can achieve this by having a counter, if the counter is 0 thread 1 executes, increments the counter and calls notyfyAll() on the counter, if the counter is 1 thread 1 calls wait() on the counter. And vice versa for thread 2.
When you execute two threads in parallel, each one of them is executed independently by the underlying operating system. The task scheduler can decide when to execute which thread. This can result in uneven time distribution like you are experiencing.
One solution for this is to use shared Semaphores to lock each thread until the other one has finished its task. Each thread would then take two semaphores, one for itself and one for the other thread. Both semaphores would start with one permit, so the first release() call doesn't block. The threads would then work like that (psudocode):
for (;;) {
otherThreadSemaphore.acquire(); // blocks until the other thread called release()
performWork();
ownThreadSemaphore.release(); // allows the other thread to perform another iteration
}
Another would be to move the infinite loop out of the threads. In each iteration of the loop you spawn both threads, then use thread.yield() to wait until both threads are finished and then the loop starts again creating two new threads. But note that creating threads can be an expensive operation, so you should only do this when the threads do considerable amount of work in each iteration so that this doesn't matter much.
I was going through threads and I read that ..The notify() method is used to send a signal to one and only one of the threads that are waiting in that same object's waiting pool.
The method notifyAll() works in the same way as notify(), only it sends the signal to all of the threads waiting on the object.
Now my query is that if Lets say I have 5 threads waiting and through Notify() , i want to send to notification to thread 3 only, what logic should be there that notification is sent to thread 3 only ..!!
You can't directly do this with wait and notify. You'd have to set a flag somewhere, have the code in the thread check it and go back to waiting if it's the wrong thread, and then call notifyAll.
Note that if you have to deal with this, it might be a sign that you should restructure your code. If you need to be able to notify each individual thread, you should probably make each of them wait on a different object.
wait-notify is rather a low level mechanism to indicate to other threads that an event (being expected occured). Example of this is producer/consumer mechanism.
It is not a mechanism for threads to communicate to each other.
If you need something like that you are looking in the wrong way.
The following code starts up five threads and sets the third one a flag which tells it that it is the only to continue. Then all of the threads that are waiting on the same lock object lock are notified (woken-up), but only the one selected continues. Be careful, writing multi-threaded applications is not easy at all (proper synchronization, handling the spurious wake-ups, etc.) You should not need to wake up only one particular thread from the group as this points to an incorrect problem decomposition. Anyway, here you go...
package test;
public class Main {
public static void main(String[] args) {
Main m = new Main();
m.start(5);
}
private void start(int n) {
MyThread[] threads = new MyThread[n];
for (int i = 0; i < n; i++) {
threads[i] = new MyThread();
/* set the threads as daemon ones, so that JVM could exit while they are still running */
threads[i].setDaemon(true);
threads[i].start();
}
/* wait for the threads to start */
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
/* tell only the third thread that it is able to continue */
threads[2].setCanContinue(true);
/* wake up all threads waiting on the 'lock', but only one of them is instructed to continue */
synchronized (lock) {
lock.notifyAll();
}
/* wait some time before exiting, thread two should be able to finish correctly, the others will be discarded with the end of the JVM */
for (int i = 0; i < n; i++) {
try {
threads[i].join(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.println("Done!");
}
/** synchronization object, i.e. a lock which makes sure that only one thread can get into "Critical Section" */
private final Object lock = new Object();
/** A simple thread to demonstrate the issue */
private final class MyThread extends Thread {
private volatile boolean canContinue;
#Override
public void run() {
System.out.println(Thread.currentThread().getName() + " going to wait...");
synchronized (lock) {
while (!canContinue) {
try {
lock.wait(1000); /* one second */
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
System.out.println(Thread.currentThread().getName() + " woken up!");
}
public void setCanContinue(boolean canContinue) {
this.canContinue = canContinue;
}
};
}
The output of the code is:
Thread-0 going to wait...
Thread-2 going to wait...
Thread-3 going to wait...
Thread-1 going to wait...
Thread-4 going to wait...
Thread-2 woken up!
Done!
So you can clearly see that only the third thread (indexed from zero) is woken up. You have to study the Java synchronization and multi-threading in more detail to understand every particular line of the code (for example, here).
I would like to help you more, but I would have to write almost a book about Java threads and that is why I just pointed out to this Java Tutorial on threads. You are right, this problematics is not easy at all, especially for beginners. So I advise you to read through the referenced tutorial and then you should be able to understand most of the code above. There is no easy way around or at least I do not know of any.