Java - Reentrant Lock, can't access newly created Condition - java

I have created a new Condition chopstickFree and in my pickUpChopstick() method, I am waiting for a lock on it but I can't get access to it at all.
Through debugging I have found that when it gets to the chopstickFree.await() line in the pickUpChopstick() method, it just pauses indefinitely
I don't understand? That code in the constructor was just an unsure attempt to get it working but either way, I have created a new condition, signaled to all that it is free, but I can't get a lock on it at all?
public class Chopstick {
Lock lock = new ReentrantLock();
private Condition chopstickFree = lock.newCondition();
private Condition chopstickInUse = lock.newCondition();
Chopstick() {
lock.lock();
chopstickFree.signalAll();
lock.unlock();
}
// Pick up chopstick
public void pickUpChopstick() throws InterruptedException {
lock.lock();
try {
chopstickFree.await(); // ALWAYS PAUSES HERE INDEFINITELY
chopstickInUse.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
// Release chopstick
public void releaseChopstick() {
lock.lock();
chopstickFree.signal();
lock.unlock();
}
}
Any ideas?
Cheers

Condition#signalAll() only signals threads that are currently in Condition#await() (or its friends), i.e. the signal isn't queued up for later calls.
You need another flag protected by the lock to correctly implement:
public class Chopstick {
private final Lock lock = new ReentrantLock();
private final Condition chopstickFree = lock.newCondition();
private volatile boolean isFree = true;
Chopstick() { /* Nothing */ }
// Pick up chopstick
public void pickUpChopstick() throws InterruptedException {
lock.lock();
try {
while (!isFree) {
chopstickFree.await();
}
isFree = false;
} finally {
lock.unlock();
}
}
// Release chopstick
public void releaseChopstick() {
lock.lock();
try {
isFree = true;
chopstickFree.signal();
} finally {
lock.unlock();
}
}
}
Here is a version using a Semaphore that might be a little closer in intent to your original implementation:
public class Chopstick {
private final Semaphore chopsticksAvailable = new Semaphore(1);
Chopstick() {
// Nothing
}
// Pick up chopstick
public void pickUpChopstick() throws InterruptedException {
chopsticksAvailable.acquire();
}
// Release chopstick
public void releaseChopstick() {
chopsticksAvailable.release();
}
}

Related

Wait for another thread to do something

I have two threads, A and B. I want the following:
I want to let A wait until B starts executing f(). Once B starts executing f(), A as well can continue its work.
If B is already executing f() when A informs B for its state, A can continue its work as well.
If however B finished executing f(), A has to wait until B starts executing f() again in the future.
In functions:
// executed by A only
public void waitForB() throws InterruptedException {
// keep waiting until B starts f()
}
// executed within aroundF() only
public void f() {
}
// executed by B only
public void aroundF() {
// 1. mark that we are executing f() and inform A
f()
// 2. unmark
}
I have been trying with Semaphore, Phaser and CyclicBarrier, but I have troubles to understand which to use here.
I managed to implement this with locking manually (see below), but I would like to understand which of the java.util.concurrent classes to use here.
private final Object lock = new Object();
private boolean executing = false;
public void waitForB() throws InterruptedException {
synchronized(lock) {
while(!executing) {
lock.wait();
}
}
}
public void f() {
}
public void aroundF() {
try {
synchronized(lock) {
executing = true;
lock.notify();
}
f();
} finally {
executing = false;
}
}
You can achieve the same semantics (and more) using java.util.concurrent.locks.Lock and an associated java.util.concurrent.locks.Condition, for instance:
public class MyClass {
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private boolean executing = false;
public void waitForB() throws InterruptedException {
lock.lock();
try {
while (!executing) {
condition.await();
}
} finally {
lock.unlock();
}
}
public void f() {
}
public void aroundF() {
try {
lock.lock();
try {
executing = true;
condition.signal();
} finally {
lock.unlock();
}
f();
} finally {
executing = false;
}
}
}

How notify second thread of variable's change

I have two threads. The first changes the value of variable Data. And second one print the value if its value has changed. I am trying to do that second thread just print each time that the variable's value changed, but I don't reach success. Someone can help me?
thread 1
class someservice{
volatile int data;
Boolean Flag = false;
public void mymethod(){
flag = true;
for (Integer i = 1; i < sheet.getRows(); i++) {
data = someMethod(); //this method when called return a new
//value
}
flag = false;
...
}
}
thread 2
Promise p = task {
try {
while (true) {
if (engineService.getFlag()) {
print(someservice.data);
}else{
break;
}
}
} catch(Throwable t) {
...
}
}
Since you mention Promises, I infer you are familiar with future/ promise in +C++11
in java there is a similar approach, with future callable...
public class HW5 {
public static void main(String[] argv) throws InterruptedException, ExecutionException {
FutureTask<Boolean> myFutureTask = new FutureTask<>(new Callable<Boolean>() {
#Override
public Boolean call() throws Exception {
// implement the logic here and return true if everything was
// ok, false otherwise.
Thread.sleep(5000);
System.out.println("dddd");
return System.currentTimeMillis() % 2 == 0;
}
});
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(myFutureTask);
Boolean result = myFutureTask.get();
System.out.println("Done!");
}
}
FutureTask in a class that takes a callable which can return an Object after its job is done... in Order to execute the Future task you can use a Executor service, especifically calling the method execute, since you need to wait for the thread to do the job then is necessary that you call Future.get, that will basically blocks the main thread until the future is done, to verify the result, just read the variable result..
You could use the notify() and notifyAll() methods within thread. Check out this link: https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
public synchronized void guardedJoy() {
// This guard only loops once for each special event, which may not
// be the event we're waiting for.
while(!joy) {
try {
wait();
} catch (InterruptedException e) {}
}
System.out.println("Joy and efficiency have been achieved!");
}
public synchronized notifyJoy() {
joy = true;
notifyAll();
}
You have to look up more data about Concurrent programming,I can tell you now some basics,well,not so so basic,but i will do my best:
Here,you have a Monitor,it is an abstract concept,in resume,a Monitor is a
class with all it's
method using"syncronized"
as modifier, it means,
that only
one thread
can access
the method
at once.So,
in the
monitor is
the variable
that you
want to print,
and the"flag",
that tells you if
the variable
was modified.Finally,
you can
see the
most important thing,the"wait()"and"notify()"methods,
those method
stops the thread,or"play"
them again.
You ask
here in
the printValue() method, if your variable was changed, if the variable was'nt change, put the thead to sleep with the wait() method, and when the other
method changeValue() is executed, the value is modified, and the notify() method is called, waking up the thread, so, doing all this, you can guarantee three things:
Safety: meaning that the threads will do that you want
Absence of deadlock: meaning that the thread that is put to sleep, will be awake in the future.
Mutex: meaning that only one thread is executing the critical code, for example, the op. "++" is not atomic, is Subdivided inside in more the one action, create a local var, read the var, sum, and asign, so, if more than one thread are in the game, the value may not be consecutive, example:
i = 0;
i ++;
output: 1;
output: 2;
output: 3;
output: 5;
output: 4;
output: 7;
That could happen, and even so, that will happen in the next code, because there a more than one thread executing. Well, this is the way to program with several threads, more or less
public class Monitor {
private int value = 0;
public static boolean valueHasChanged = false;
public synchronized int changeValue(int newValue){
this.value = newValue;
Monitor.valueHasChanged = true;
this.notify();
return this.value + 1;
}
public synchronized void printValue(){
while(!Monitor.valueHasChanged){
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(this.value);
Monitor.valueHasChanged = false;
}
public static void main(String[] args) {
Monitor ac = new Monitor();
BClass t1 = new BClass(ac);
AClass t2 = new AClass(ac);
t1.start();
t2.start();
}
public int getValue() {
return this.value;
}
}
Now the threads:
public class AClass extends Thread{
private Monitor ac;
public AClass(Monitor ac) {
this.ac = ac;
}
#Override
public void run() {
while(true){
this.ac.printValue();
}
}
}
And finally:
public class BClass extends Thread{
private Monitor ac;
public BClass(Monitor ac) {
this.ac = ac;
}
#Override
public void run() {
int v = 0;
while(true){
this.ac.changeValue(v);
v++; // this sum is not secure, if you want to print an
// ascending order, the code is diferent, I will show in
// above.
}
}
Now, if you want an ordered print:
the monitor will look like:
public class Monitor {
private int value = 0;
public boolean valueHasChanged = false;
private boolean hasPrint = true;
public synchronized void changeValue(int newValue) {
this.value = newValue;
this.valueHasChanged = true;
this.notify();
}
public synchronized void changeValuePlusOne() {
while (!hasPrint) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.value++;
this.valueHasChanged = true;
this.hasPrint = false;
this.notifyAll();
}
public synchronized void printValue() {
while (!this.valueHasChanged) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(this.value);
this.valueHasChanged = false;
this.hasPrint = true;
this.notifyAll();
}
public static void main(String[] args) {
Monitor ac = new Monitor();
BClass t1 = new BClass(ac);
AClass t2 = new AClass(ac);
t1.start();
t2.start();
}
public int getValue() {
return this.value;
}
}
And the Threads:
public class BClass extends Thread{
private Monitor ac;
public BClass(Monitor ac) {
this.ac = ac;
}
#Override
public void run() {
while(true){
this.ac.changeValuePlusOne();
}
}
}
The other Thread look equals:
public class AClass extends Thread{
private Monitor ac;
public AClass(Monitor ac) {
this.ac = ac;
}
#Override
public void run() {
while(true){
this.ac.printValue();
}
}
}

How to use a lock in Java to wait for the special condition?

I have an object:
public class Resource {
private Lock lock = new ReentrantLock();
private boolean processed = false;
public Lock getLock() {
return lock;
}
public boolean isProcessed() {
return processed;
}
public void setProcessed(boolean processed) {
this.processed = processed;
}
}
I want to stop the thread "one" untill the thread "two" changes the variable "processed" to true. After "processed" is set to true I want to wake up the thread "one" and continue doing some stuff.
I know that we can use wait and notify methods to organize it but it is very dangerous because of interruptions.
If I will use only wait and notify methods there may be a situation when I wait infinity.
If our wait method is interrupted by some reason, we check that the "process" variable is still false after that we can use wait again like here:
while(true){
if(!resource.isProcessed()){
resource.getLock().wait();
}
else{
break;
}
}
It is dangerous to use the code like this because after we checked "!resource.isProcessed()" and before we use "resource.getLock().wait()" another process can set the "process" to true and call "resource.getLock().notify()" (which will not take any effect because we haven't yet called "wait()").
How to wait for some condition safely? How to notify/unlock safely some condition?
As Peter Lawrey answered in comments there are Condition available in java. (Thank you for pointing)
Here is a copy past of the example which is available in the documentation:
class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}
You can use a CountDownLatch to make one thread await until an operation performed by another thread is completed.
Let's suppose T1 and T2 are your threads and they share a CountDownLatch initialized with a counter of 1. T1 will first await() on the latch, while T2 should perform its operation and then invoke countDown() on the latch to let T1 proceed.
Of course await() in T1 can still be interrupted, so you may want to call it in a loop.
class T1 implements Runnable {
private final CountDownLatch latch;
T1(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
awaitUninterruptibly(latch);
doWork();
}
private void awaitUninterruptibly(CountDownLatch latch) {
boolean interrupted = false;
try {
while (true) {
try {
latch.await();
return;
} catch (InterruptedException e) {
interrupted = true;
}
}
} finally {
if (interrupted) {
Thread.currentThread().interrupt();
}
}
}
}
class T2 implements Runnable {
private final CountDownLatch latch;
T1(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
doWork();
latch.countDown();
}
}

How can I start, pause and resume my threads? (by extending thread from classes)

Essentially, what I want to do is start all my threads, pause them all, then resume them all, using the multithreading approach. I am just looking for a simple solution to this. I'm not sure if I have to use a timer or what. Right now when I run it, the threads are like being executed in random order (I guess the PC is just randomly picking which ones it wants to run at a certain time).
class ChoppingThread extends Thread
{
public void run()
{
for(int j=40;j!=0;j-=10)
System.out.println("Chopping vegetables...("+j+" seconds left)");
}
}
class MixingThread extends Thread
{
public void run()
{
for(int k=60;k!=0;k-=10)
System.out.println("Mixing sauces...("+k+" seconds left)");
}
}
class TenderizingThread extends Thread
{
public void run()
{
for(int j=50;j!=0;j-=10)
System.out.println("Tenderizing meat...("+j+" seconds left)");
}
}
class MultiThreadTasking
{
public static void main (String [] args)
{
ChoppingThread ct = new ChoppingThread();
MixingThread mt = new MixingThread();
TenderizingThread tt = new TenderizingThread();
System.out.println("\nWelcome to the busy kitchen.");
//putting threads into ready state
ct.start();
mt.start();
tt.start();
}
}
There are probably other ways to achieve the same result, but this is the simplest I can come up with off the top of my head (I know, sad isn't it)...
Basically, this is a special Runnable with some additional management functionality.
This basically contains a state flag that indicates the state of the task and a monitor lock
public class ThreadFun {
public static void main(String[] args) {
MyTask task = new MyTask();
Thread thread = new Thread(task);
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
task.pauseTask();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
task.resumeTask();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
task.stopTask();
}
public enum TaskState {
Running,
Stopped,
Paused
}
public static class MyTask implements Runnable {
private static final Object PAUSED_LOCK = new Object();
private volatile TaskState state = TaskState.Running;
public void pauseTask() {
if (state == TaskState.Running) {
System.out.println("Paused...");
state = TaskState.Paused;
}
}
public void resumeTask() {
if (state == TaskState.Paused) {
state = TaskState.Running;
synchronized (PAUSED_LOCK) {
PAUSED_LOCK.notifyAll();
}
System.out.println("Resumed...");
}
}
public void stopTask() {
if (state == TaskState.Running || state == TaskState.Paused) {
state = TaskState.Stopped;
System.out.println("Stopped...");
}
}
public boolean isStopped() {
return state == TaskState.Stopped;
}
public boolean isPaused() {
return state == TaskState.Paused;
}
protected void doPause() {
synchronized (PAUSED_LOCK) {
while (isPaused()) {
try {
PAUSED_LOCK.wait();
} catch (InterruptedException ex) {
}
}
}
}
#Override
public void run() {
int index = 0;
while (!isStopped() && index < 1000) {
try {
Thread.sleep(25);
} catch (InterruptedException ex) {
}
doPause();
index++;
System.out.println(index);
}
stopTask(); // Make sure the task is marked as begin stopped ;)
}
}
}
The main criteria is you will need to pool isStopped and doPause at appropriate points to ensure that they are begin implemented as required...
To coordinate them use a CyclicBarrier.
To launch them all at the same time use a CountDownLatch.
Google the two classes above for many examples and explanations.
To fully understand what is happening read the Java Concurrency In Practice book.
I believe you can accomplish this by using Object.wait and Thread.interrupt.
Object.wait blocks until notify is called. So
private boolean paused;
private Object waitObject;
...
public void run() {
for ... {
if (this.paused) { this.waitObject.wait(); }
...
public void pause() { this.paused = true; }
public void resume() { this.paused = false; this.waitObject.notify(); }
Then you can call pause to pause the thread.
Thread.interrupt can help with stopping.
private boolean paused;
...
public void run() {
for ... {
// interrupted() is different from interrupt()!
if (this.iterrupted()) { break; }
...
To stop it, you would call interrupt() from another thread.
This is the basic idea, but there's a lot of details to worry about here. For example, wait can throw an InterruptedException you'll need to handle. Also, wait is not guaranteed to return only after a notify. It can return randomly. Here is a pair of tutorials:
Wait: http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
Interrupt: http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

Threading and locking in my program

I'm new to multithreading and having a problem with threads and locking in my program.
I have simplified my problem by creating the code below
private final ConcurrentLinkedQueue<String> valueQueue = new ConcurrentLinkedQueue<String>();
private final Object lock = new Lock();
private ProcessValue processor = new ProcessValues();
public void addValue(String value){
synchronized (lock) {
valueQueue.add(value);
lock.notify();
}
}
public void waitForValuesToBeAdded(){
synchronized (lock) {
lock.wait();
executeValues();
}
}
public void executeValues(){
synchronized (lock) {
processor.processValues();
valueQueue.clear();
lock.notify()
}
}
When the program starts it executes waitForValuesToBeAdded. As the name suggests this just waits for values to be added to the queue. When values are added we no longer wait and so executeValues() is called.
When processor.processValues() is executing I don't want values to be added to the Queue (valueQueue.add(value)). I need them to wait until processValues() has finished.
I thought if I use a synchronized block it will block the insertion but when I add another value while processValue is executing everything hangs.
Have I missed something in my program?
Try using jvisualvm to see where threads are blocked. You can do a "thread dump" to analize this.
Rewrite as follows:
private final ConcurrentLinkedQueue<String> valueQueue = new ConcurrentLinkedQueue<String>();
private final Object lock = new Lock();
private ProcessValue processor = new ProcessValues();
public void addValue(String value) {
synchronized (lock) {
valueQueue.add(value);
lock.notifyAll();
}
}
public void waitForValuesToBeAdded() throws InterruptedException {
synchronized (lock) {
while (valueQueue.size() == 0) {
lock.wait();
}
executeValues();
}
}
public void executeValues() {
synchronized (lock) {
processor.processValues();
valueQueue.clear();
lock.notifyAll()
}
}

Categories