deadlock using Semaphore - java

I have a simple question about managing Threads. I have 3 process that share the same Semaphore with one permit. in normal situation, the first process takes this permit and release two permit tho the second process. The second process release 3 permits to the third process. I given an example to illustrate my problem.
First one:
public class Process0 extends Thread{
Semaphore s;
public Process0(Semaphore s){
this.s = s;
}
public void run(){
try {
sleep(20000);
s.acquire();
System.out.println("hello");
} catch (InterruptedException ex) {
Logger.getLogger(Process.class.getName()).log(Level.SEVERE, null, ex);
}
s.release(2);
}
}
Second Process:
public class Process1 extends Thread{
Semaphore s;
public Process1(Semaphore s){
this.s = s;
}
public void run(){
try {
this.sleep(10000);
s.acquire(2);
System.out.println("Hello 2");
} catch (InterruptedException ex) {
Logger.getLogger(Process1.class.getName()).log(Level.SEVERE, null, ex);
}
s.release(3);
}
}
And last one:
public class Process2 extends Thread{
Semaphore s;
public Process2(Semaphore s){
this.s = s;
}
public void run(){
try {
System.out.println("Acquire process 3 ");
s.acquire(3);
System.out.println("Hello 3");
} catch (InterruptedException ex) {
Logger.getLogger(Process2.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
The problem is. When i run this three process and be sure that process 3 is the first that excute the acquire. I will have a deadlock. Process 2 never print "Hello 3" and process 1 never print "Hello 2".Why ?
Semaphore s = new Semaphore(1);
Process0 p = new Process0(s);
Process1 p1 = new Process1(s);
Process2 p2 = new Process2(s);
p.start();
p1.start();
p2.start();

Your Semaphore is constructed as new Semaphore(1), which only has one permit available to be acquired. The call s.acquire(3) will never return since the semaphore will never have three permits available. The attempt to acquire a single permit by Process also blocks since acquisitions are ordered and Process2 arrived "first":
The release method javadoc states that an acquisition can happen when
Some other thread invokes the release() method for this semaphore and the current thread is next to be assigned a permit.
This minimal, single-thread example will show you:
Semaphore s = new Semaphore(1);
s.acquire(2);
System.out.println("Didn't deadlock!");
The solution to this is to use Semaphore.acquire() which requests one permit, or Semaphore.acquire(1) which also requests only one permit.
You also need to make sure that you acquire and release the same amount of permits, unless you have a very good reason to misuse Semaphore. From Javadoc:
There is no requirement that a thread that releases a permit must have acquired that permit by calling acquire [or that a thread releases all of its permits]. Correct usage of a semaphore is established by programming convention in the application.
Additionally, it seems that you might be using the wrong synchronizer for this task. You could use a CyclicBarrier or other class usable for synchronization.

It took me some time to find out what you wanted to accomplish. Here's what I've come up with. Hope it helps.
The problem is that threads in your implementation are trying to acquire lock in some order. So thread waiting for 3 permits waits first, then comes the thread waiting for 2 permits, and obviously stands in line waiting for his 2 permits, then comes the first thread wanting just 1 permit. There is one permit available so it's good to go. Then it returns 2 permits. Unfortunately next in line is thread waiting for 3 permits, not that waiting for 2. Bummer. Blocked. That's what you observe.
If you made other threads to change places in line for acquire, everything would be fine. Here comes
s.tryAcquire(int permits)
and suddenly everything works fine.
I'll make example based on your code, with 1s sleep in busy wait loop to see what's going on.
import java.util.concurrent.Semaphore;
class Process0 extends Thread {
Semaphore s;
public Process0(Semaphore s){
this.s = s;
}
public void run(){
try {
sleep(20000);
s.acquire();
System.out.println("hello");
} catch (InterruptedException ex) {
System.out.println(Process.class.getName());
}
s.release(2);
System.out.println("released 2");
}
}
class Process1 extends Thread{
Semaphore s;
public Process1(Semaphore s){
this.s = s;
}
public void run(){
try {
this.sleep(10000);
while(!s.tryAcquire(2)) {
System.out.println("Busy waiting for 2 permits");
sleep(1000);
}
System.out.println("Hello 2");
} catch (InterruptedException ex) {
System.out.println(Process.class.getName());
}
s.release(3);
System.out.println("Released 3");
}
}
class Process2 extends Thread{
Semaphore s;
public Process2(Semaphore s){
this.s = s;
}
public void run() {
System.out.println("Acquire process 3 ");
while(!s.tryAcquire(3)) {
System.out.println("Busy waiting for 3 permits");
try {
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Hello 3");
}
}
public class DaemonTest {
public static void main(String[] args) {
Semaphore s = new Semaphore(1);
Process0 p = new Process0(s);
Process1 p1 = new Process1(s);
Process2 p2 = new Process2(s);
p.start();
p1.start();
p2.start();
}
}

Related

Join a two different ExecutorService

I wanted to join two threads that are getting executed in ExecutorService.
public class CURD {
public static ExecutorService executorService = Executors.newCachedThreadPool();
#Autowired
Logging logging;
public void Update(List<? extends HBase> save, List<? extends HBase> delete) {
Thread t = new Thread(() -> {
System.out.println("Started Main Thread...");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("End Main Thread...");
},"Thread-1");
logging.setPredecessor(t);
executorService.submit(t);
}
}
Second Class:
This class thread should wait for the first thread to complete.
But it doesn't wait for the first thread to complete.
I am not sure if this is the right way to do it.
Please can someone let me know how to join two threads that are getting executed in an ExecutorService?
import static com.demo.executorService;
public class Logging {
private Thread predecessor;
public void setPredecessor(Thread t) {
this.predecessor = t;
}
private void loggingInfo() {
Thread run = new Thread( () ->{
try {
if (predecessor != null) {
System.out.println(Thread.currentThread().getName() + " Started");
predecessor.join();
System.out.println(Thread.currentThread().getName() + " Finished");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
addTask(run);
}
public void addTask(Runnable run) {
System.out.println("Runnable Thread logAround.....");
CompletableFuture.runAsync((run), executorService).exceptionally(ex -> {
System.out.println("exception occurred " + ex);
return null;
});
}
}
If one wants to synchronize among a set of threads one can use
the Java CyclicBarrier class:
A synchronization aid that allows a set of threads to all wait for
each other to reach a common barrier point. CyclicBarriers are useful
in programs involving a fixed sized party of threads that must
occasionally wait for each other. The barrier is called cyclic because
it can be re-used after the waiting threads are released.
To achieve that, first create the CyclicBarrier object with the correspondent number of parties, namely:
private final CyclicBarrier barrier = new CyclicBarrier(NUMBER_OF_PARIES);
Formally from the Java doc one can read that parties are:
the number of threads that must invoke {#link #await} before the barrier is tripped
Informally, parties are the number of threads that will have to call the cyclic barrier and wait, before all of them can move forward.
Afterward, you need to pass the barrier instance object reference to each of the threads that should wait, and invoke wait (i.e., barrier.await()), accordingly. Something as follows:
public void Update(..., CyclicBarrier barrier) {
Thread t = new Thread(() -> {
System.out.println("Started Main Thread...");
try {
Thread.sleep(1500);
barrier.await(); // <--- wait on the barrier
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("End Main Thread...");
},"Thread-1");
...
}
Repeat this process to the other threads that must wait. Ensure that the number of parties (i.e., NUMBER_OF_PARIES) matches the number of threads that should wait on the cyclic barrier, otherwise deadlocks will occur.
Now that you are using the cyclic barrier you can clean up some parts of your code, for instance, you can remove all the logic related to the field predecessor of the Logging class.
If you just want to make Thread 2 wait for Thread 1, then you can use CountDownLatch, instead.
A synchronization aid that allows one or more threads to wait until a
set of operations being performed in other threads completes. A
CountDownLatch is initialized with a given count. The await methods
block until the current count reaches zero due to invocations of the
countDown() method, after which all waiting threads are released and
any subsequent invocations of await return immediately. This is a
one-shot phenomenon -- the count cannot be reset. If you need a
version that resets the count, consider using a CyclicBarrier.
First create the CountDownLatch object with only 1 count:
private final CountDownLatch block_thread2 = new CountDownLatch(1);
and pass it to the Thread 2, and since you want this thread to wait for the Thread 1, call block_thread2.await();
Thread run = new Thread( () ->{
try {
....
block_thread2.await(); // wait for Thread 2
} catch (InterruptedException e) {
// deal with it
}
});
...
and to the Thread 1 add wait.countDown();:
public void Update(...) {
Thread t = new Thread(() -> {
System.out.println("Started Main Thread...");
try {
Thread.sleep(1500);
wait.countDown();
} catch (InterruptedException e) {
// deal with it
}
System.out.println("End Main Thread...");
},"Thread-1");
...
}
So, in this manner, Thread 2 will wait for Thread 1, but Thread 1 will never wait for Thread 2.

Notifying two threads at the same time

How can I notify Thread t1 and Thread t2 at the same time (so it is the same probability to get hey 1 as hey2 first)? I've tried notifyAll, but couldn't make it work.
class Thr extends Thread
{
Thr () throws InterruptedException
{
Thread t1 = new Thread() {
public synchronized void run()
{
while (true)
{
try {
wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try
{
Thread.sleep(1500);
} catch (Exception e) { }
System.out.println("hey 1");
}
}
};
Thread t2 = new Thread() {
public synchronized void run()
{
while (true)
{
try {
wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try
{
Thread.sleep(1500);
} catch (Exception e) { }
System.out.println("hey 2");
}
}
};
t1.start();
t2.start();
}
public static void main(String args[]) throws InterruptedException
{
new Thr();
}
}
You should wait on a shared object and use notifyAll as in:
class Thr extends Thread
{
Thr () throws InterruptedException
{
final Object lock = new Object ();
Thread t1 = new Thread() {
public void run()
{
try {
synchronized (lock) {
lock.wait();
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("hey 1");
}
};
Thread t2 = new Thread() {
public synchronized void run()
{
try {
synchronized (lock) {
lock.wait();
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("hey 2");
}
};
t1.start();
t2.start();
synchronized (lock) {
lock.notifyAll ();
}
}
public static void main(String args[]) throws InterruptedException
{
new Thr();
}
}
The right way to do this is to use notifyAll. The real problem with your code seems to be that you have two threads waiting for notifications on different mutexes. You need them to wait on a single object ... as described in #ShyJ's answer.
Note that there is NO WAY that you can code this so that the notification is guaranteed to be delivered first to either thread with equal probability:
The Java threading specs make no guarantees of fairness in wait / notify.
The thread scheduler implemented (typically) at the OS-level (typically) makes no such guarantees either.
The point is that the application has no control over this. The best approach is to just let wait/notifyAll do what they normally do, and design your application so that any bias in the thread scheduling does not affect the application's behaviour in an important way.
(FWIW, the usual problem is that people explicitly or implicitly assume non-randomness ... and get burned when threads get scheduled in an unexpectedly random order.)
I highly recommend avoiding the use of wait/notify and use something more robust. The problem is that using wait/notify in any combination will likely result in a race condition.
The only way to give equal probability to them academically is to create two Semaphore objects, have the threads try to acquire them, and use Random to choose which one to release first. Even then, if the scheduler decides to run the first one that tried to obtain the lock, then you get bias there anyway, regardless of whether or not the Sempahore is fair. This forces you to wait until the first thread is done before running the second, such as via Thread.join.
Bottom line, the only way to guarantee order in a concurrent system is to force them into a single-threaded format, which throws out the whole point of having them concurrent in the first place.
If you are using Java versions greater than 1.4, then it would greatly simplyfy your task by using any of the concurrent locks:
java.util.concurrent.locks specially the ReadWrite type.
For now for message passing to all the threads at the same type - implement Observer Pattern

About wait and notifyAll

I've this class:
public class MyThread implements Runnable {
private static boolean canAccess = true;
private Thread t;
public FirstThread(String name) {
t = new Thread(this);
t.setName(name);
}
public void start() {
t.start();
}
private synchronized void accessed(String name) throws InterruptedException {
if (canAccess) {
canAccess = false;
System.out.println("Accessed " + name);
try {
Thread.sleep(5000);
} catch (Exception e) {
}
canAccess = true;
System.out.println("NOTIFY: " + name);
notifyAll();
}
System.out.println("WAIT: " + name);
wait();
}
#Override
public void run() {
while (true) {
try {
accessed(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
And this is my output:
Accessed 1
WAIT: 3
WAIT: 5
WAIT: 7
WAIT: 9
WAIT: 0
WAIT: 2
WAIT: 4
WAIT: 6
WAIT: 8
NOTIFY: 1
WAIT: 1
and my app freeze (deadlock state).
Seems that the notifyAll method doesn't work. Where is my error?
My Main class.
public class Main {
public static void main(String[] args) {
MyThread [] threads = new MyThread[10];
for(int i=0;i<threads.length;i++) {
threads[i] = new MyThread(""+i);
threads[i].start();
}
}
}
wait means that the thread releases the lock and goes into a dormant state until another thread notifies it. notifyAll means that the thread tells all the other threads waiting on the lock being used in the current synchronized block to wake up and try to acquire the lock again. Your code example doesn't have any cases where multiple threads are trying to acquire the same lock so using wait and notifyAll here doesn't make any sense. There's nothing to wake up the thread once it calls wait.
One typical use of wait and notify: You might have many producers putting stuff in a queue, and consumer threads that take stuff out of the queue. The queue has a take method that the consumer calls, if the queue is empty then it calls wait and the consumer blocks. The queue has a put method that calls notifyAll when something goes into the queue so that any waiting consumer threads wake up.
There's a producer-consumer example of using wait and notifyAll in the Java tutorial.
Every Thread waits on it's own instance, that's why they all are stuck in one place.
If you had a private static Object LOCK = new Object(); and call LOCK.wait(); and LOCK.notify(); this could be another story.
I have also doubts about synchronized modifier for accessed() method. It's just doesn't have use in the described situation. I would better modify the "canAccess" variable in synchronized block.

Why does java thread wait() work only with time limit in here?

I am trying to get familiar with Java threads for the SCJP and I had a question.
In the below-written code i simply created:
two Runnables with
a common data storage (an array) and
a synchronized write() method to fill it with data successively leaving a letter as a mark for each Runnable (A and B) in sequence.
I know the code is rough and could be better written but I was seeking the moral of the threads.
So now when I run it, it never terminates and the results stop at:
Still good.
A0.
But when I change wait() to wait(100) it works just fine counting from 0 to 9 and it terminates normally. Could someone explain the reason behind that for me please?
Thank you.
public class ArrayThreads {
Object[] array = new Object[10];
boolean isA = true;
int position = 0;
int getIndex(){
return position;
}
class ThreadA implements Runnable{
synchronized void write(String value){
while(!isA){
try {
wait();
} catch (InterruptedException ex) {
System.out.println("An error in" + value);
ex.printStackTrace();
}
}
array[position] = value + position;
System.out.println(array[position]);
position++;
isA = !isA;
notify();
}
public void run() {
while(getIndex()<array.length){
if (getIndex()==9) return;
else
write("A");}
}
}
class ThreadB implements Runnable{
synchronized void write(String value){
while(isA){
try {
wait();
} catch (InterruptedException ex) {
System.out.println("An error in" + value);
ex.printStackTrace();
}
}
array[position] = value + position;
System.out.println(array[position]);
position++;
isA = !isA;
notify();
}
public void run() {
while(getIndex()<array.length){
if (getIndex()==9) return;
else
write("B");}
}
}
public static void main(String[] args){
ArrayThreads threads = new ArrayThreads();
Thread threadA = new Thread(threads.new ThreadA());
Thread threadB = new Thread(threads.new ThreadB());
System.out.println("Still good");
threadB.start();
threadA.start();
}
}
Your threads are each waiting and notifying separate objects - so they're not communicating with each other at all. If you want them to effectively release each other, they'll need a shared monitor to synchronize, wait on and notify.
It's "working" when you specify a timeout because it's effectively turning the wait call into a sleep call... still nothing is really waiting/notifying usefully, because the two threads are still dealing with separate monitors.
your objects are not working in same monitor.
you need to either move the wait() and notify() to same object like:
http://www.java-samples.com/showtutorial.php?tutorialid=306
or you can notify the target object:
http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ315_016.htm
when you set wait(100). you are setting a timeout. and definitely it will wake up after 100ms.

IllegalMonitorException using Semaphore and Monitor in Java

I have a project for my "Operating Systems". I need to write 2 programs with java...
write a program that produce Water with 2 method Oxygen and Hydrogen.
method Oxygen produce one Oxygen and method Hydrogen produce one hydrogen. when 2 Hydrogen and one Oxygen was existed H2O created. I must write this with with Semaphores and threads.
Write the above problem with Monitors and Sychronize.
I've writed some code for this but it gives illegal monitor exeption...
please help me to correct it...
This is my code:
// class for implement Thread for oxygen
public class Thread_O implements Runnable {
public void run() {
thread t = new thread();
try {
t.oxygen();
} catch (InterruptedException ex) {
Logger logger = Logger.getLogger(Thread_O.class.getName());
logger.log(Level.SEVERE, null, ex);
}
}
}
// class for implement Thread for Hydrogen
public class Thread_H implements Runnable {
public void run() {
thread t = new thread();
try {
t.Hydrogen();
} catch (InterruptedException ex) {
Logger logger = Logger.getLogger(Thread_H.class.getName());
logger.log(Level.SEVERE, null, ex);
}
}
}
//class for method Oxygen and Hydrogen
public class thread {
Semaphore O = new Semaphore(0, true);
Semaphore H = new Semaphore(0, true);
Semaphore H2O = new Semaphore(0, true);
Semaphore safe = new Semaphore(1, true);
public void oxygen() throws InterruptedException {
safe.wait();
H.wait();
H.wait();
H2O.release();
H2O.release();
Safe.release();
// System.out.println("O2...!");
}
public void Hydrogen() throws InterruptedException {
H.release();
H2O.wait();
// System.out.println("H2...!");
}
}
and in action of Oxygen Button:
Thread th = new Thread(new Thread_O());
th.start();
I'm not going to decode your homework for you, but an IllegalMonitorException is thrown when you're trying to wait() on an object without being synchronized. So to wait for an object called list:
synchronized (list) {
try {
list.wait();
} catch(Throwable t) {
t.printStackTrace();
}
}
You have to understand how the producer/consumer mechanism work.
Here you'll have one consumer thread and two producers.
First you'll have one thread producing oxygen, and other producing hydrogen.
Then, those molecules should be places "somewhere" ok? That "something" is the thing that has to be monitored and synchronized.
So it should go something like this:
class Water {
char [] waterMolecule = new char[3]; // <-- synchronize access to this
char hydrogen(){
return 'H';
}
char oxygen() {
return 'O';
}
void produce() {
Thread t = new Thread( new Runnable() {
synchronize( waterMolecule ) {
waterMolecule[0] = hydrogen();
}
}):
.... produce the others
}
void consume() {
synchronize watermolecule
if waterMolecule is complete
create water and clean out the molecule.
}
}
That's the basic idea.
Just bear in mind that you won't be able to produce another particle of oxigen until the previous one has been consumed.
Also you must always call wait in a while loop
Here's how that wait/synchronize should be coded.
Here's a number of producer/consumer samples.
Although your homework is already due, I'd like to propose CyclicBarrier as the best solution for this scenario.
It allows some kind of rendezvous for the different threads (here: your molecule producers) and triggers the execution of an additional runnable on completition (here: creation of h20).

Categories

Resources