I am trying to learn multithreading and was trying with a cyclic barrier. I understand that to break the barrier an await method must be called by the number of the thread mentioned while creating the barrier. I am trying to do the same but when I check if the barrier is broke my main method is going in an infinite loop.
class CyclicBarrierTrial implements Runnable{
CyclicBarrier barrier;
public CyclicBarrierTrial(CyclicBarrier barrier){
this.barrier=barrier;
}
public void run() {
System.out.println("in the run method");
try {
Thread.sleep(1000);
System.out.println("going to call awake on barrier"+ Thread.currentThread().getName());
try {
barrier.await();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("barrier broke");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//System.out.println("Wake up from the Sleep"+ Thread.currentThread().getName());
}
}
public class MYCountDownLatch {
public static void main(String[] args) throws InterruptedException {
CyclicBarrier barrier = new CyclicBarrier(2);
Thread t1= new Thread(new CyclicBarrierTrial((barrier)));
t1.start();
Thread t2= new Thread(new CyclicBarrierTrial((barrier)));
Thread.sleep(2000);
t2.start();
while(!barrier.isBroken())
{
System.out.println("waiting for the barrier to break "+barrier.isBroken());
}
System.out.println("MAIN THREAD finally barrier to broke ");
}
}
barrier.isBroken() indicates if barrier is in broken state, which is different than barrier is tripper.
To check this, you can try interrupting one of thread, this will raise BarrierBrokenException on other threads and barrier.isBroken() will be true.
Thread.currentThread().interrupt();
If you want to wait for all threads to complete, then you can use ExecutorService.awaitTermination or Thread.join
From documentation:
If any thread is interrupted while waiting, then all other waiting threads will throw BrokenBarrierException and the barrier is placed in the broken state.
Hope this help.
Related
According to How to use wait and notify in Java? I have to synchronized on the same object to call notify.
I have synchronized on the same haveCoffee object. Why I am getting IllegalMonitorStateException when I call the notify method ?
I am Sleeping
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at com.example.concurrent.basic.WaitAndNotify$2.run(WaitAndNotify.java:42)
in the following code:
public class WaitAndNotify {
public static void main(String[] args) {
Thread haveCoffee = new Thread() {
public void run() {
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("I am awake and ready to have coffee");
}
}
};
Thread me = new Thread() {
public void run() {
synchronized (haveCoffee) {
try {
System.out.print("I am Sleeping");
Thread.sleep(4000);
notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
haveCoffee.start();
me.start();
}
}
On the first Thread, you call wait on an object while having its monitor (the object being this haveCoffee).
However, on the second thread, you call notify() on me, while having the monitor of haveCoffee.
This should work:
public class WaitAndNotify {
public static void main(String[] args) {
final Thread haveCoffee = new Thread() {
public void run() {
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("I am awake and ready to have coffee");
}
}
};
Thread me = new Thread() {
public void run() {
synchronized (haveCoffee) {
try {
System.out.print("I am Sleeping");
Thread.sleep(4000);
haveCoffee.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
haveCoffee.start();
me.start();
}
}
From oracle documentation page,
public class IllegalMonitorStateException
extends RuntimeException
Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
Whenever you get this exception, just go through your code and check wait() and notify() calls and the object on which these calls have been invoked. You can easily figure out what went wrong.
EDIT:
wait() or notify() calls have to be invoked on object once you get monitor on that object.
You should be calling
haveCoffee.notify()
instead of just
notify().
If you invoke just notify() it calls the notify() method on the this object which is the second thread me where as you have synchronized on haveCoffee thread and that is the reason for exception you are seeing.
So the code in thread2 me should looks like:
synchronized (haveCoffee) {
try {
System.out.print("I am Sleeping");
Thread.sleep(4000);
haveCoffee.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
I'm trying to create a thread and then interrupt it. But it doesn't stop and cause exception. Can anybody explain what am I doing wrong? Thanks.
public class Test {
public static void main(String[] args) throws InterruptedException {
//Add your code here - добавь код тут
TestThread test = new TestThread();
test.start();
Thread.sleep(5000);
test.interrupt();
}
public static class TestThread extends Thread {
public void run() {
while (!this.isInterrupted()) {
try {
Thread.sleep(1000);
System.out.println("I did the Thread");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
According to javadocs:
A thread interruption ignored because a thread was not alive at the
time of the interrupt will be reflected by this method returning
false.
Since you sleep the thread for 1000ms, when you call test.interrupt(), thread is asleep, almost all the times. So InterruptedException will be thrown. Therefore you should exit the loop at the catch clause.
Include a break when you catch InterruptedException to exit while loop.
while (!this.isInterrupted()) {
try {
Thread.sleep(1000);
System.out.println("I did the Thread");
} catch (InterruptedException e) {
break;
}
}
The internal flag gets resetted after calling interrupt.
You have to call it again in your catch of the thread.
The topic was also covered in the Java Specialists Newsletter
In my example, after I caught the InterruptedException, I used
Thread.currentThread().interrupt() to immediately interrupted the
thread again. Why is this necessary? When the exception is thrown, the
interrupted flag is cleared, so if you have nested loops, you will
cause trouble in the outer loops
Something like this should work:
try {
Thread.sleep(1000);
System.out.println("I did the Thread");
} catch (InterruptedException e) {
this.interrupt();
// No need for break
}
This makes sure that the rest of the code is executed.
I cant understand why t3 isn't getting starved, since there is only one lock and there is always some high priority thread waiting on it (as I see it, if t1 acquire the lock, t2 waits, and the opposite. So why does t3 get the lock?
public class Starvation {
public static int count = 0;
public static void main(String[] args){
final CountDownLatch latch = new CountDownLatch(3);
final Object lock = new Object();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
try {
latch.countDown();
latch.await();
while(count<100){
synchronized (lock) {
count++;
System.out.println("Count 1");
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
try {
latch.countDown();
latch.await();
while(count<100){
synchronized (lock) {
count++;
System.out.println("Count 2");
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Thread t3 = new Thread(new Runnable() {
#Override
public void run() {
try {
latch.countDown();
latch.await();
while(count <100){
synchronized (lock) {
count++;
System.out.println("Count 3");
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.MAX_PRIORITY);
t3.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
t3.start();
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I cant understand why t3 isn't getting starved, since there is only one lock and there is always some high priority thread waiting on it (as i see it, if t1 acquire the lock, t2 waits, and the opposite.. so why t3 do get the lock?
The priority of typical thread implementations specifically will try hard not to starve threads. If there are threads with higher priorities then they may run more than t3 but t3 will be given cycles. Also, if your hardware has more than 2 CPU, t3 may be scheduled on a dormant CPU regardless of the priorities of the other threads.
For example, I've seen thread priority systems that keep the priority and a priority-counter. Every time the thread gets a time slice its priority-counter is decremented. Then when it reaches 0 it is put back to the max again. This means that at some point a lower priority thread will have a equal or higher priority-counter and will get cycles. But this is OS specific and there are probably other ways to accomplish it.
Really the priority of the threads should be considered to be a hint to the underlying OS. I very rarely if ever have used priorities at all although I've written a lot of thread code.
class myThreadRun implements Runnable
{
public void run() {
roo();
}
public synchronized void roo()
{
System.out.println("In thread before wait " + Thread.currentThread().getName());
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JOptionPane.showMessageDialog(null, "After wait in\n"+Thread.currentThread().getName());
System.out.println("In thread after wait " + Thread.currentThread().getName());
//notify();
}
public synchronized void foo()
{
notify();
}
}
public class ThreadingDemo {
public synchronized void Start()
{
System.out.println("Labamba");
myThreadRun mThRun = new myThreadRun();
Thread thread = new Thread(mThRun);
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//mThRun.foo(); //This works
//mThRun.notify(); //crash
//thread.notify();//crash
try {
thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
new ThreadingDemo().Start();
}
This is simple code to demonstrate wait() and notify(),
In the myThreadRun class run() method just does wait() and foo() method does notify()
as indicated in the code above, if I do mThRun.notify() the program crashes, but mThRun.foo() runs the without a hitch and gives the much needed result. I need to know why?
You need to own the monitor for the object to all obj.wait() and obj.notify().
That is why it works when called within the synchronized block on mThRun but not outside. So if you put the mThRun.notify(); in a synchronized block, it works, like this:
synchronized (mThRun) {
mThRun.notify();
}
In your case you are getting an IllegalMonitorStateException.
Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
Put another way, you don't hold the lock of the object you are trying to notify. Having the lock of a different object doesn't help.
When you use notify() and wait() you need to change a state and check for it. If you don't do this, you can find that either
notify() is called before wait() and the signal is lost
wait() wakes prematurely
You cannot assume notify/wait is a reliable messaging protocol.
I suggest you consider using the concurrency library which is a better choice in most cases from Java 5.0 (2004)
May be you are going very hard with wait/notify. Its very simple. what you need to know is which object is used for monitor lock. To make the same code working i have modified the same code: ( I have put MAK comment where i changed the code, hope its helpful)
class MyThreadRun implements Runnable {
public void run() {
roo();
}
public synchronized void roo() {
System.out.println("In thread before wait " + this);
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
JOptionPane.showMessageDialog(null, "After wait in\n" + Thread.currentThread().getName());
System.out.println("In thread after wait " + Thread.currentThread().getName());
}
}
public class ThreadingDemo {
public static void main(String[] args) {
MyThreadRun mThRun = new MyThreadRun();
System.out.println("Labamba: " +mThRun);
Thread thread = new Thread(mThRun);
thread.start();
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
//mThRun.foo(); //This works //MAK: no sense
//mThRun.notify(); //crash //MAK: Need monitor lock
synchronized (mThRun) {
mThRun.notify();//crash //MAK: will work now
}
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Main2 {
public static void main(String[] args) {
new Test2().start();
new Test2().start();
}
}
class Test2 extends Thread {
#Override
synchronized public void run() {
try {
System.out.println("begin wait");
wait();
} catch (Exception ex) {
}
}
}
As the actual result of running the test:
begin wait,
begin wait,
two times from the two threads.
Contrast to the expected result:
begin wait,
only one time from one of the two threads because wait() is called inside the synchronized run() method.
Why could call to Object's wait() break thread synchronization?
Thans a lot!
public class Main3 {
public static void main(String[] args) {
Test3 t = new Test3();
new Thread(t).start();
new Thread(t).start();
}
}
class Test3 implements Runnable {
synchronized public void run() {
try {
System.out.println("begin wait");
wait();
} catch (Exception ex) {
}
}
}
#akf & #Sean Owen
Thanks for your replies. Sorry for my mistake, now i modified the code to place the synchronization on the same object's run(), the result remained: begin wait, begin wait, two times.
#akf
wait will release the lock that
synchronize has grabbed, and will be
re-gotten once the thread is notified.
Could you elaborate a little bit?
The object that you are synchronizing on in this example is not the class, but the instance, so each new Test2 object would be synchronizing on a different monitor.
The method you might be looking for here is sleep, not wait. wait will release the lock that synchronized has grabbed, and will be re-gotten once the thread is notified.
Note that for your test to work correctly, you will need to lock on a common object. If you want to see wait in action, I have thrown together a simple app that will pop up a frame with a "Notify" button. Two threads will be started that wait on a common object and are in turn notified when the button is pressed.
public static void main(String[] args)
{
final Object lock = new Object();
final JFrame frame = new JFrame("Notify Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Notify");
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt) {
synchronized(lock) {
lock.notify();
}
}
});
frame.add(button);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.setVisible( true );
}
});
new Thread(new Runnable() {
public void run() {
synchronized(lock) {
try {
System.out.println("1. starting");
lock.wait();
System.out.println("1. step 1");
lock.wait();
System.out.println("1. step 2");
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
public void run() {
synchronized(lock) {
try {
System.out.println("2. starting");
lock.wait();
System.out.println("2. step 1");
lock.wait();
System.out.println("2. step 2");
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
}).start();
}
For a simple explanation of wait, the JavaDoc is always a good place to start:
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).
The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
You have two different Test2 objects. Synchronized methods lock on the object. They are not acquiring the same lock, so no it should print twice.
an simple example that can help you is this:
public class test {
public static void main(String[] args) {
Prova a=new Prova();
new Test2(a).start();
new Test2(a).start();
}
}
class Prova{
private boolean condition;
public void f(){
while(condition){
//Thread.currentThread Returns a reference to the currently executing thread object.
//Thread.getName() return name Thread
System.out.println(Thread.currentThread().getName()+" begin wait");
try{
wait();
}catch(InterruptedException c){return;}
}
System.out.println(Thread.currentThread().getName()+" first to take the mutex");
condition=true;
}
}
class Test2 extends Thread {
private Prova a;
private static boolean condition;
public Test2(Prova a){
this.a=a;
}
#Override
public void run() {
synchronized(a){
try {
a.f();
} catch (Exception ex) {
}
}
}
}
in this case the two threads synchronize an object, the first taking the lock release message, the second one waits. in this example uses the condition variable
summary to wait/notify mechanism:
1)current thread reaches one object's synchronized code block which contains the call to wait(), it competes with other threads for the lock(the object's monitor), as winner it executes the block till the call to wait() encounters.
2)by calling wait(), current thread releases the lock to other competing threads, then halts execution, wait for notify being sent from another thread who succeeds in obtaining the lock.
JavaDoc:
A thread becomes the owner of
the object's monitor in one of three
ways:
•By executing a synchronized instance
method of that object.
•By executing
the body of a synchronized statement
that synchronizes on the object.
•For
objects of type Class, by executing a
synchronized static method of that
class.
3)another thread reaches the same object's yet another synchronized code block which contains the call to notify/notifyAll(), it competes with other threads for the lock, as winner it executes the block till finishing the call to notify/notifyAll(). It will release the lock either by call to wait() or at the end of the execution on the block.
4)upon receiving notify/notifyAll(), current thread competes for the lock, as winner the execution continues where it has halted.
simple example:
public class Main3 {
public static void main(String[] args) {
Test3 t = new Test3();
new Thread(t).start();
new Thread(t).start();
try {
Thread.sleep(1000);
} catch (Exception ex) {
}
t.testNotifyAll();
}
}
class Test3 implements Runnable {
synchronized public void run() {
System.out.println(Thread.currentThread().getName() + ": " + "wait block got the lock");
try {
wait();
} catch (Exception ex) {
}
System.out.println(Thread.currentThread().getName() + ": " + "wait block got the lock again");
try {
Thread.sleep(1000);
} catch (Exception ex) {
}
System.out.println(Thread.currentThread().getName() + ": " + "bye wait block");
}
synchronized void testNotifyAll() {
System.out.println(Thread.currentThread().getName() + ": " + "notify block got the lock");
notifyAll();
System.out.println(Thread.currentThread().getName() + ": " + "notify sent");
try {
Thread.sleep(2000);
} catch (Exception ex) {
}
System.out.println(Thread.currentThread().getName() + ": " + "bye notify block");
}
}
output:
Thread-0(or 1): wait block got the
lock
Thread-1(or 0): wait block got
the lock
main: notify block got the
lock
main: notify sent
main: bye notify block
Thread-0(or 1): wait block
got the lock again
Thread-0(or 1): bye
wait block
Thread-1(or 0): wait block
got the lock again
Thread-1(or 0): bye
wait block