Thread wait() affects the Main thread ? [duplicate] - java

This question already has answers here:
What's the difference between Thread start() and Runnable run()
(14 answers)
Closed 7 years ago.
Consider this simple try for a multithreading example :
public class LetsMutexThreads {
public static Object MUTEX = new Object();
private static class Thread1 extends Thread {
public void run() {
synchronized (MUTEX)
{
System.out.println("I'm thread 1 , goint to take a nap...");
try
{
MUTEX.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("T1 : That's it , I'm done ...");
}
}
}
private static class Thread2 extends Thread {
public void run() {
synchronized (MUTEX)
{
System.out.println("Thread 2 : Let's rock N roll !");
System.out.println("Waking up my buddy T1 ...");
MUTEX.notify();
}
}
}
public static void main(String[] args)
{
Thread2 t2 = new Thread2();
Thread1 t1 = new Thread1();
t1.run();
t2.run();
}
}
I'm trying to allow Thread1 to go to sleep with the wait , and then let Thread2
to use notify() to wake Thread1 , but he doesn't get a chance .
Why does the wait() of Thread1 affects the Main Thread from executing t2.run(); ?

You must not attempt to start a thread using the run() method. It does not actually create a new thread, it runs the code in the current thread. Use thread.start() instead in order to have your code executed in a separate (new) thread

This is wrong:
Thread2 t2 = new Thread2();
Thread1 t1 = new Thread1();
t1.run();
t2.run();
Change it to this:
Thread2 t2 = new Thread2();
Thread1 t1 = new Thread1();
t1.start();
t2.start();

Related

What happens to data members in Threading in Java?

Can anyone please explain what happens to data members while threading? I mean in the below code the output is as I wanted i.e thread name with its corresponding number.However if I pass the reference of 1 thread to all the other threads the thread name varies but the number 50 is printed for all the thread names.Why does this happen?
class Thread3 implements Runnable
{
int x;
public void run()
{
for(int i=1;i<=5;i++)
{
System.out.println(Thread.currentThread().getName()+" "+ x);
try{
Thread.sleep(1000);
}catch(Exception e){ }
}
}
}
public class RunThread3 {
public static void main(String s[])
{
Thread3 t1=new Thread3();
t1.x=50;
Thread tt1=new Thread(t1,"thread1");
tt1.start();
Thread3 t2=new Thread3();
t2.x=100;
Thread tt2=new Thread(t2,"thread2");
tt2.start();
Thread3 t3=new Thread3();
t3.x=150;
Thread tt3=new Thread(t3,"thread3");
tt3.start();
for(int i=1;i<=5;i++)
{
System.out.println(Thread.currentThread().getName());
try{
Thread.sleep(1000);
}catch(Exception e){ }
}
}
}
Here reference of 1 thread passed to all others
class Thread3 implements Runnable
{
int x;
public void run()
{
for(int i=1;i<=5;i++)
{
System.out.println(Thread.currentThread().getName()+" "+ x);
try{
Thread.sleep(1000);
}catch(Exception e){ }
}
}
}
public class RunThread3 {
public static void main(String s[])
{
Thread3 t1=new Thread3();
t1.x=50;
Thread tt1=new Thread(t1,"thread1");
tt1.start();
Thread3 t2=new Thread3();
t2.x=100;
Thread tt2=new Thread(t1,"thread2");
tt2.start();
Thread3 t3=new Thread3();
t3.x=150;
Thread tt3=new Thread(t1,"thread3");
tt3.start();
for(int i=1;i<=5;i++)
{
System.out.println(Thread.currentThread().getName());
try{
Thread.sleep(1000);
}catch(Exception e){ }
}
}
}
In the later code you are passing reference of thread t1 to all:
Thread3 t1=new Thread3();
t1.x=50;
Thread tt1=new Thread(t1,"thread1");
tt1.start();
Thread tt2=new Thread(t1,"thread2");
tt2.start();
Thread tt3=new Thread(t1,"thread3");
tt3.start();
This means all thread will be having value of x as 50 and when you execute the code you will get the expected value:
thread1 50
thread2 50
main
thread3 50
main
thread1 50
thread3 50
thread2 50
thread1 50
main
thread3 50
thread2 50
thread3 50
main
thread2 50
thread1 50
main
thread3 50
thread2 50
thread1 50
In the former case you are having different threads and they work accordingly.
It is your misunderstanding of threading and classes in java.
In your code you have 2 different entities: java Thread and your custom Runnable class.
Name of thread that you got in your sample is name of java Thread object. Number x that you got in your sample is number of your custom Runnable class. Please note: I skipped name of your class - it makes misunderstanding. So if you use only one your custom Runnable object - you'll always got single x value.

what is the assurity for JVM to start run() method of Threads in a sequence

For this below program, the ans is --> print : printName , then wait for 5 seconds then print : printValue
But as far as I know that its up to JVM to pick a thread and start its run method. So why it cannot be (printvalue printname and then 5 sec pause).
Note : I understand the conept of synchornized method but how we are sure here that JVM will always pick the thread t1 as its first thread.
class B {
public synchronized void printName() {
try {
System.out.println("printName");
Thread.sleep(5 * 1000);
} catch (InterruptedException e) {
}
}
public synchronized void printValue() {
System.out.println("printValue");
}
}
public class Test1 extends Thread {
B b = new B();
public static void main(String argv[]) throws Exception {
Test1 t = new Test1();
Thread t1 = new Thread(t, "t1");
Thread t2 = new Thread(t, "t2");
t1.start();
t2.start();
}
public void run() {
if (Thread.currentThread().getName().equals("t1")) {
b.printName();
} else {
b.printValue();
}
}
}
In this context, the synchronize just means that they can't run at the same time, not that they have to run in order. If you want them to run in order, then you don't want threads, or you want a more sophisticated queuing mechanism.
So, you are correct in that the it could either be "printName" pause "printValue" or "printValue" "printName" pause.
If you run the program multiple times, you'll likely see the first one more frequently. You will see the second output occasionally. The skew is because there is a slight delay between the start() on thread 1 and start() on thread 2.
how we are sure here that JVM will always pick the thread t1 as its first thread.
You can never be sure that the t1 thread will start running before the t2 thread starts running. If you need the t1 thread to do something before the t2 thread does some other thing, then you will have to use some synchronization object (e.g., a Semaphore) to make t2 wait.
Semaphore semaphore = new Semaphore(0);
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
doTheThingThatHasToBeDoneFirst();
semaphore.release();
doOtherStuff();
}
}).start();
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
semaphore.acquire(); //will not return until t1 thread calls release().
doOtherOtherStuff();
}
}).start();
But that is not really a smart way to use threads. Why not just do this instead?
doTheThingThatHasToBeDoneFirst();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
doOtherStuff();
}
}).start();
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
doOtherOtherStuff();
}
}).start();
As a rule of thumb, the more synchronization you have between your threads, the less benefit you get from using threads. If you want certain things to happen in a certain order, you should do those things in that order in a single thread.
The trick to using threads is to design your program so that there are useful things it can do where order does not matter.

Implementing deadlock condition

I am trying to implementing deadlock condition but somehow I am not able to get it working. Both the threads Thread1 and Thread2 are entering in the run function but only one of them enters in Sub/Sum depending on who entered run first. Example : if Thread2 entered run first the it will call sub() and Thread1 never calls sum(). I have also added sleep time so that Thread2 sleeps before calling sum() and Thread1 gets enough time to enter Sum() but Thread1 never enters.
public class ExploringThreads {
public static void main(String[] args) {
// TODO Auto-generated method stub
threadexample a1 = new threadexample();
Thread t1 = new Thread(a1, "Thread1");
Thread t2 = new Thread(a1,"Thread2");
t1.start();
t2.start();
}
}
class threadexample implements Runnable{
public int a = 10;
public void run(){
if(Thread.currentThread().getName().equals("Thread1"))
sum();
else if(Thread.currentThread().getName().equals("Thread2"))
sub();
}
public synchronized void sum()
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"In Sum");
sub();
}
public synchronized void sub()
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"In Sub");
sum();
}
}
If you really want to create an artificial dead lock, try this:
Thread1 and Thread2 are two threads that want to access the same file.
Thread1 starts, asks for a lock on File1.docx and sleeps for 2 minutes.
Thread2 starts, and makes an exclusive lock on File2.docx and now wants to access File1.docx.
Thread1 wakes up and now wants to access File2.docx which is held by Thread2
Now, this is a circular wait condition
Simple ? =)
This is not how you get a deadlock. Actually this code seems pretty safe :-) Only one thread enters sum/sub at a time because you are using synchronized which synchronizes on "this". There is only one "this" so both threads try to acquire the same lock.
Deadlock occurs, for instance, when Thread1 has one lock, Thread2 has second lock and then Thread1 would like to acquire Thread2's lock while still holding it's lock and Thread2 would like to acquire Thread1's lock while still holding it's lock.
What you could do is:
a) add 2 objects for locking in "threadexample" class (btw classes by convention should start with uppercase):
private final Object sumLock = new Object();
private final Object subLock = new Object();
b) drop the "synchronized" keyword in both sum/sub methods and instead use the synchronized() {} block in each of them. Sum would be synchronized(sumLock) { /* sum's body goes here / } and sub would be synchronized(subLock) { / sub's body goes here */}.
In this case Thread1 would go into sum(), acquire the sumLock and wait. Thread2 would go into sub(), acquire the subLock() and wait. Thread1 would wake up, go into sub() and try to acquire subLock but it's being held by Thread2 so it wait's until Thread2 releases it. In that time Thread2 wakes up, goes into sum() and tries to acquire sumLock which is held by Thread1 so Thread2 waits for Thread1 to release it.
Neither thread will go forward as each one of them is waiting for the other - you have a deadlock.
#Edit: yes you have only 1 instance of "threadexample" and both Thread1 and Thread2 are fighting for the lock but when one of them acquires the lock it will release it after executing sum/sub or sub/sum. For instance let's say Thread1 is first and starts executing sum(). It has the lock. In that case Thread2 will not go into sub() as it is protected by the same lock as Thread1. Thread1 will do sum(), then sub() and then it will release the lock --> Thread2 will go into sub() etc.
This is a working example of 'Deadlock in Action'. Basically what you need to do (and how that usually happens in real world) is that object are locked in opposite order: a first, b second in one thread and b first, a second in another:
package stackoverflow;
public class Deadlock {
final static String a = new String("A");
final static String b = new String("B");
public static void main(String[] args) {
final Thread abLock = new Thread() {
#Override
public void run() {
lock(a, b);
}
};
final Thread baLock = new Thread() {
#Override
public void run() {
lock(b, a);
}
};
abLock.start();
baLock.start();
}
static void lock(String first, String second) {
synchronized (first) {
System.out.println(first);
sleep();
synchronized (second) {
System.out.println(second);
}
}
}
static void sleep() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}

Synchronization with threads

I have a two part question...
I have a class with a function in it that can only be accessed by any one thread at a given time. Making this a synchronized function or a synchronized block still allows for multiple threads since different threads are accessing it within the class. How can I make sure only one thread accesses this code? (See code example below)
With the synchronized function, the calls to the function are queued up. Is there any way to only allow the last call to the function to access the code? So if I have Thread1 currently accessing my function, then Thread2 and Thread3 try to access it (in that order) only Thread3 will be given access once Thread1 is complete.
public void doATask() {
// I create a new thread so the interface is not blocked
new Thread(new Runnable() {
#Override
public void run() {
doBackgroundTask();
}
}).start();
}
private void doBackgroundTask(MyObject obj) {
// perform long task here that is only being run by one thread
// and also only accepts the last queued thread
}
Thanks for any help!
If the second thread in your example can just return, you could use a combination of a lock and keeping track of the last thread executing the method. It could look like this:
private volatile Thread lastThread;
private final ReentrantLock lock = new ReentrantLock();
private void doBackgroundTask(Object obj) throws InterruptedException {
Thread currentThread = Thread.currentThread();
lastThread = currentThread;
try {
// wait until lock available
lock.lockInterruptibly();
// if a thread has arrived in the meantime, exit and release the lock
if (lastThread != currentThread) return;
// otherwise
// perform long task here that is only being run by one thread
// and also only accepts the last queued thread
} finally {
lock.unlock();
}
}
Full working test with additional logging that shows the thread interleaving and that T2 exits without doing nothing:
class Test {
private volatile Thread lastThread;
private final ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) throws Exception {
final Test instance = new Test();
Runnable r = new Runnable() {
#Override
public void run() {
try {
instance.doBackgroundTask(null);
} catch (InterruptedException ignore) {}
}
};
Thread t1 = new Thread(r, "T1");
Thread t2 = new Thread(r, "T2");
Thread t3 = new Thread(r, "T3");
t1.start();
Thread.sleep(100);
t2.start();
Thread.sleep(100);
t3.start();
}
private void doBackgroundTask(Object obj) throws InterruptedException {
Thread currentThread = Thread.currentThread();
System.out.println("[" + currentThread.getName() + "] entering");
lastThread = currentThread;
try {
// wait until lock available
lock.lockInterruptibly();
// if a thread has arrived in the meantime, exit and release the lock
if (lastThread != currentThread) return;
// otherwise
// perform long task here that is only being run by one thread
// and also only accepts the last queued thread
System.out.println("[" + currentThread.getName() + "] Thinking deeply");
Thread.sleep(1000);
System.out.println("[" + currentThread.getName() + "] I'm done");
} finally {
lock.unlock();
System.out.println("[" + currentThread.getName() + "] exiting");
}
}
}
Output:
[T1] entering
[T1] Thinking deeply
[T2] entering
[T3] entering
[T1] I'm done
[T1] exiting
[T2] exiting
[T3] Thinking deeply
[T3] I'm done
[T3] exiting
What you want is probably a worker thread that waits for a signal to do some work. doATask() simply sends a signal to trigger the work. Accumulative signals are equivalent to one signal.
final Object lock = new Object();
MyObject param = null;
public void doATask(arg)
synchronized(lock)
param=arg;
lock.notify();
MyObject awaitTask()
synchronized(lock)
while(param==null)
lock.wait();
tmp=param;
param=null;
return tmp;
// worker thread
public void run()
while(true)
arg = awaitTask();
doBackgroundTask(arg);

Two threads entering synchronized methods of runnable

Here is a code i am having problem with --
public class WaitTest {
public static void main(String[] args) {
Runner rr = new Runner();
Thread t1 = new Thread(rr,"T1");
Thread t2 = new Thread(rr,"T2");
t1.start();
t2.start();
}
}
class Runner implements Runnable{
int i=0;
public void run(){
try{
if(Thread.currentThread().getName().equals("T1")){
bMethod();
aMethod();
}
else{
aMethod();
bMethod();
}
}catch(Exception e){}
}
public synchronized void aMethod() throws Exception{
System.out.println("i="+i+",Now going to Wait in aMethod "+Thread.currentThread().getName());
Thread.currentThread().wait();
System.out.println("Exiting aMethod "+Thread.currentThread().getName());
}
public synchronized void bMethod() throws Exception{
System.out.println("i="+i+",Now going to Wait bMethod "+Thread.currentThread().getName());
i=5;
notifyAll();
System.out.println("Exiting bMethod "+Thread.currentThread().getName());
}
}
The output is :
i=0,Now going to Wait bMethod T1
Exiting bMethod T1
i=5,Now going to Wait in aMethod T1
i=5,Now going to Wait in aMethod T2
My question is :
Why T2 enters in aMethod while T1 is waiting inside? and Why T2 prints
i=5 in aMethod.
When you execute wait, your thread releases the lock and enters the wait state. At this time the other thread is allowed to enter the method. You are using a single instance of Runnable so when one thread sets it to 5, that's what the other thread reads.
1. wait will immediately release the lock, and handover the lock to the other thread.
2. notify will release the lock only when the closing parenthesis of the synchronized block
is reached.
3. As there is only one instance of Runnable here, its after the i = 5, and when the synchronized block ends..then the lock is released.
This code is not doing the wait-notify pattern. The Thread.currentThread().wait() call throws an IllegalMonitorStateException, which is caught and ignored by the run method. Both T1 and T2 throws this exception, and hence you do not see the line Exiting aMethod printed.
The notify call in bMethod is wasted, because no thread ever waits on the intrinsic lock of the rr Runnable.

Categories