I have one static Semaphore instance.
Semaphore semaphore = new Semaphore(1);
Now I have two Threads (Sending Thread and Receiving Thread)
Sending Thread:
public class SendingThread implements Runnable {
private Semaphore semaphore;
public SendingThread(Semaphore semaphore){
this.semaphore = semaphore;
}
#Override
public void run() {
try {
System.out.println("1");
Thread.sleep(4000);
this.semaphore.acquire();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
}
and receiving Thread:
public class RecievingThread implements Runnable {
private Semaphore semaphore;
public RecievingThread(Semaphore semaphore){
this.semaphore = semaphore;
}
#Override
public void run() {
System.out.println("2");
this.semaphore.release();
System.out.println("3");
}
}
When I start this 2 threads according to my understanding Receiving Thread will wait for 4 second till
Sending Thread will notify it that Receiving Thread can continue. It means that System.out.println("3"); will be printed with 4 second delay, but when I run this code all three values are printed immediately. Why?
Am i missing something?
A new Semaphore(1) has 1 initial permit and thus allows for one immediate acquire to go through. Furthermore since a release is always allowed both threads proceeds immediately.
To force one thing to happen before the other, you can use new Semaphore(0). This will force the thread calling acquire to wait for the thread executing release.
Related
I have a situation in my application where events come in and the thread that handles them (signalling thread) must signal to another thread (working thread), thus far in an idle state, that it can run some code. Once the working thread is done it should wait to be signalled again. It is possible that events will arrive while the working thread is working. In this case it should move on and keep working immediately. One action by the working thread does enough work for any amount of incoming events, so there is no need to work once per event, just once as soon as possible after each event. Example correct behavior:
event comes in
worker thread starts work
worker thread finishes work
event comes in
worker thread starts work
event comes in
event comes in
worker thread finishes work
worker thread starts work
worker thread finishes work
4 events, 3 periods of work. It's an unfortunate but unavoidable requirement that the signalling thread cannot block while handling the event. I have implemented this at the moment using a BlockingQueue, which has the pointless side effect of filling itself up even though the contents are not interesting or even looked at. I was expecting to be able to make this work using CountDownLatch or CyclicBarrier or similar but I haven't been able to find a way. Here is my implementation:
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
public class Main {
private static final class MyBarrier {
private BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
void await() throws InterruptedException {
queue.take();
queue.clear();
}
void signal() {
queue.add(true);
}
}
private static Random random = new Random(0);
private static void sleepForMax(int maxMillis) {
sleep(random.nextInt(maxMillis));
}
private static void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public static void main(String[] args) {
MyBarrier myBarrier = new MyBarrier();
final ExecutorService singallingThread = Executors.newSingleThreadExecutor();
singallingThread.submit(() -> {
while (!Thread.currentThread().isInterrupted()) {
sleepForMax(1_000); // simulate period between events arriving
myBarrier.signal();
System.out.println("Signalling work to be done");
}
System.out.println("Thread interrupted");
});
final ExecutorService workingThread = Executors.newSingleThreadExecutor();
workingThread.submit(() -> {
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.println("Waiting for work");
myBarrier.await();
} catch (InterruptedException e) {
break;
}
System.out.println("Doing work...");
sleepForMax(3_000); // simulate work being done
System.out.println("Work done");
}
System.out.println("Thread interrupted");
});
sleep(10_000);
singallingThread.shutdownNow();
workingThread.shutdownNow();
}
}
What's the better way to do this?
When I run your code with your implementation that uses Phaser, having changed the sleep times so that signalling occurs every 800 ms and processing takes 1000 ms, I get e.g. this output:
00008: Waiting for work
00808: Signalling work to be done
00808: Doing work... <-- worker starts working
01608: Signalling work to be done <-- signal came, so there's more work
01808: Work done
01809: Waiting for work <-- waits for work...
02409: Signalling work to be done <-- ...for 600 ms, until the next signal
02409: Doing work...
(The number to the left is milliseconds since start. Also, you can reproduce it with your code with random delays, but that's harder to reproduce and see there.)
If I understood it correctly, this is wrong. E.g. imagine what happens if signals stop coming.
Your code can probably work with this adjustment for your specific case:
private static final class MyBarrierWithPhaser {
private final Phaser phaser = new Phaser(1);
private int lastObservedPhase; // Phaser has initial phase 0
void await() throws InterruptedException {
// only works for 1 producer 1 worker; lastObservedPhase is kind of thread-local
lastObservedPhase = phaser.awaitAdvanceInterruptibly(lastObservedPhase);
}
void signal() {
phaser.arrive();
}
}
With this, the worker records the last phase it advanced to, and if the signal thread "arrives" before the next awaitAdvanceInterruptibly, then the Phaser phase gets updated, and when worker tries to wait using a stale phase, it will progress immediately; if the signal thread does not arrive before awaitAdvanceInterruptibly, then the worker will wait until the signal thread finally arrives.
Using simpler synchronization primitives, I can think of how to implement it using the synchronized-wait()-notify() mechanism:
private static final class MyBarrierWithSynchronized {
private boolean hasWork = false;
synchronized void await() throws InterruptedException {
while (!hasWork) {
wait();
}
hasWork = false;
}
synchronized void signal() {
hasWork = true;
notifyAll(); // or notify() if we are sure there is 1 signal thread and 1 worker thread
}
}
It has a couple of drawbacks: await() won't be interrupted if the thread is waiting to enter it. Also, some don't like synchronizing on this, I kept it so in order to be short. This can be rewritten using the java.util.concurrent.* analogues, this implementation will not have both of these drawbacks:
private static final class MyBarrierWithLock {
private boolean hasWorkFlag = false;
private final Lock lock = new ReentrantLock();
private final Condition hasWorkCond = lock.newCondition();
void await() throws InterruptedException {
lock.lockInterruptibly();
try {
while (!hasWorkFlag) {
hasWorkCond.await();
}
hasWorkFlag = false;
} finally {
lock.unlock();
}
}
void signal() {
lock.lock();
try {
hasWorkFlag = true;
hasWorkCond.signalAll(); // or signal() if we are sure there is 1 signal thread and 1 worker thread
} finally {
lock.unlock();
}
}
}
I'm experimenting with this, using java.util.concurrent.Phaser, which may work, but I haven't used Phaser before so I'm not sure.
private static final class MyBarrier2 {
private Phaser phaser = new Phaser(1);
void await() throws InterruptedException {
phaser.awaitAdvanceInterruptibly(phaser.getPhase());
}
void signal() {
phaser.arrive();
}
}
I have a problem to understand Locks and Conditions in Java, i do not understand why my code ends up in a deadlock. My programm consists of a Mainthread and a Subthread, subthread is a member of Mainthread. Both threads run in an infinite loop, Subthread's loop is supposed to execute exactly one iteration as soon as it receives the signal for startCond from the Mainthread. Mainthread should wait for the finishCond signal to continue.
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
public static void main(String[] args) {
LockTest lt = new LockTest();
Mainthread m1 = lt.new Mainthread();
m1.start();
}
public class Mainthread extends Thread {
private Subthread sub = new Subthread();
public void run(){
System.out.println("Main start");
sub.start();
while(!isInterrupted()) {
try {
sub.getStartLock().lock();
sub.getStartCond().signal();
sub.getStartLock().unlock();
sub.getFinishLock().lock();
sub.getFinishCond().await();
sub.getFinishLock().unlock();
System.out.println("Main done");
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Subthread extends Thread {
private Lock startLock = new ReentrantLock();
private Lock finishLock = new ReentrantLock();
private Condition startCond = startLock.newCondition();
private Condition finishCond = finishLock.newCondition();
public Lock getStartLock() {
return startLock;
}
public Lock getFinishLock() {
return finishLock;
}
public Condition getStartCond() {
return startCond;
}
public Condition getFinishCond() {
return finishCond;
}
public void run() {
System.out.println("Sub start");
while(!isInterrupted()) {
try {
startLock.lock();
startCond.await();
startLock.unlock();
finishLock.lock();
finishCond.signal();
finishLock.unlock();
System.out.println("Sub done");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
My expected output would be:
Main done Sub done
(repeated as many times as it was executed in the loops).
Is there a way to solve this problem easier?
The main thread starts, it creates new sub thread and starts it but calling start on a thread does not mean that the thread would receive the processor imeddiatly and that its code will be actually executed.
Main, callss sub.getStartCond().signal(); but at this moment the sub thread is still not running so it misses this signal.
Main, awaits on the finishCond.
Sub starts executing its run method, it goes to the start condition and waits on it for ever.
The deadlock.
Signal wakes up only CURRENTLY waiting thread, it does not 'remember' previous calls.
Use Semaphore instead http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html
it has the semantic of 'counting the permits'.
There might be a more reliable way to do this. I would recommend using a CountDownLatch initialized with a count of 1, instead of a condition. Both the main and child threads can share the same instance of the latch (since the main owns the child that should be easy). The child will call await() and the main will call countDown() when you need to send the signal to the child. I recommend you make the latch private and final.
class ChildThread extends Thread {
private final CountDownLatch signal;
public ChildThread(CountDownLatch signal) {
this.signal = signal;
}
public void run() {
// The loop is necessary in case we get interrupted.
while (true) {
try {
signal.await();
break;
} catch(InterruptedException ignored) {
}
}
// do the work...
}
}
class MainThread extends Thread {
private final ChildThread child;
private final CountDownLatch signalToChild;
public MainThread() {
signalToChild = new CountDownLatch(1);
child = new ChildThread(signalToChild);
}
public void run() {
// I can start the child right away but I'd rather make sure it
// starts if the main thread has started.
child.start();
// prework
// let's signal the child
signalToChild.countDown();
// now the child is working, let's go on with the main thread work
}
}
This works because main and child thread actually share state, i.e., the latch. It does not matter if the main thread decrements the latch before the child thread is actually started, because the child will check this shared state to know if it can start.
I've been trying to make a simple Java thread application, where one thread waits, and another wakes it up after 3 seconds. However, I can't seem to make it work and I just can't figure out why.
public class Deadlock extends Thread {
Object lock = new Object();
public static void main(String[] args) {
//WAITER THREAD
Deadlock waiter = new Deadlock() {
#Override
public void run() {
System.out.println("Waiter started");
synchronized(lock) {
try{
System.out.println("Waiter will wait for notify...");
lock.wait();
System.out.println("Woke up!");
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}//run()
};
//WAKER THREAD
Deadlock waker = new Deadlock() {
#Override
public void run() {
System.out.println("Waker started");
synchronized(lock) {
System.out.println("Waker sleeping for 3 seconds.");
try{
Thread.sleep(3000);
}catch(InterruptedException e) {}
System.out.println("Waker notifying...");
lock.notifyAll();
}
}//run
};
waiter.start();
waker.start();
}
}
The output I get is:
Waiter started
Waiter will wait for notify...
Waker started
Waker sleeping for 3 seconds.
Waker notifying...
...and keeps running forever. I expected the waiter thread to wake up and the program to terminate.
Thanks
Your main problem is that the 'lock' is a class instance property so the two Deadlock instances do not share the same 'lock'. Hence, calling notifyAll() in the waker has no effect on the waiter because it's waiting on a different object. The simplest solution is to make 'lock' static:
static Object lock = new Object();
... I'd also make it private and final for good measure.
The second issue is that by starting the two threads together you don't really guarantee that the waiter will run first - I'd add a short delay before starting the waker.
So, I have a server like this:
public class Server {
private ExecutorService executor = null;
private class WorkerThread implements Runnable{
public void run() {
try{
do{
synchronized(executor){
executor.wait();
}
// doSomeThing
}while(true);
} catch (InterruptedException e) {
}
}
}
Server() {
executor = Executors.newCachedThreadPool();
}
public void calledWhenTriggerEventOccurs(){
synchronized(executor) {
executor.execute(new WorkerThread());
executor.notify();}
}
}
After calledWhenTriggerEventOccurs() is called for 3 times in a row, 3 new threads are being placed in the executors pool. Then I just wait for 90 sec.
I now would expect the previous 3 threads to be dead. But they are still alive.
When I call calledWhenTriggerEventOccurs() once again a 4th thread is being created.
So why are those 3 threads not being removed as I would expect?
Your tasks most likely wait forever so I wouldn't expect them to die, no matter how long you wait. When you notify() and there isn't any threads waiting the notify is lost. Most likely you have notified three times before your three tasks have a chance to start.
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.