wait() - notify() mechanism in java malfunctioning in a strange way [duplicate] - java

This question already has answers here:
Why should wait() always be called inside a loop
(11 answers)
Closed 7 years ago.
I've tried reading some answers to similar questions here (I always do that) but did not find (or did not understand?) the answer to this particular issue.
I am implementing a fairly simple consumer-producer class, which receives elements to a list from a different thread and consumes them repeatedly. The class has the following code:
public class ProduceConsume implements Runnable
{
LinkedList<Integer> _list = new LinkedList<Integer>();
public synchronized void produce(Integer i)
{
_list.add(i);
notify();
}
public void run()
{
while(true)
{
Integer i = consume();
// Do something with the integer...
}
}
private synchronized Integer consume()
{
if(_list.size() == 0)
{
try
{
wait();
}
catch(InterruptedException e){}
return _list.poll();
}
}
}
The problem is - it usually works fine, but sometimes, the execution gets to
return _list.poll();
with the list still empty. I can't wrap my head around it - am I doing something terribly wrong? Shouldn't the runnable thread, which repeatedly tries to poll detect a zero length list, wait, and be awakened only after the producer method is done, hence making the list non-empty?
Nothing else "touches" the class from the outside, except for calls to produce. No other threads are synchronized on the runnable class.
By the way, for several reasons, I wish to use my own variant and not classes such as CopyOnWriteArrayList, etc.
Thanks! Any help would be greatly appreciated.
P.S - I have not used the wait-notify many times, but when I did, in the past, it worked. So if I apologize if I made some huge stupid error!

As the Javadoc for Object.wait states
As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
Additionally, you shouldn't ignore an exception like InterruptedException. This will look like a spurious wake up and as you say produces an error.
private synchronized Integer consume() {
try {
while (_list.isEmpty())
wait();
return _list.poll();
} catch(InterruptedException e) {
throw new IllegalStateException("Interrupted");
}
}

Since wait releases the lock you can't reason based on conditions tested before it started waiting, assuming the condition must have changed once wait is exited is not valid. You need to call wait in a loop, so that once the thread ceases waiting and takes the lock again, it checks that the condition it's waiting for has the expected value:
private synchronized Integer consume()
{
try {
while (_list.size() == 0) {
wait();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return _list.poll();
}
From the Oracle tutorial:
Note: Always invoke wait inside a loop that tests for the condition being waited for.
Also it's not safe to assume that just because wait returned that something sent a notification. wait can return even if there is no notification (the spurious wakeup).
It's hard to say what caused what you're seeing without a complete working example.
The linked Oracle tutorial page has a Producer Consumer example you might want to look at.

Related

Trying to implement mutex and synchronization in Java

First of all, I think that all my problems could be more or less solved if I made my method which incurs in a race condition of the type synchronized. I cant use it, because I want to be "manually" able to check if there is a Thread currently using the method, put it to wait until the previous thread finishes and then manually awaken it/notify so the new thread can execute the method.
I am new to Threading in general and Java threading in particular. Any suggestion would be much appreciated.
**Problem**:
I am trying to start a bunch of threads of the same class.
Below you can see its run method.
#Override
public void run() {
if (!lck.tryLock()) { //sort of mutex
System.out.println(this.toString() + "waiting");
try {
synchronize();
} catch (InterruptedException ex) {
}
}
methodRaceCondition(this);
condition=true; //variable i am tryng to use to make the method below "awaken" the waiting threads.
lck.unlock();
}
I created a Lock (ReentrantLock) so I can check if there is a thread currently using the method with critical section -so i avoid race condition.
If there is one thread using this methodRaceCondition, I want to make the newcomer thread wait. I used a new method for it, bc as far as I know you can just make a thread wait and notify inside a synchronized method (and, I cant/dont want to use it, see above), so I created this synchronized method.
public synchronized void synchronize() throws InterruptedException {
while(!condition) {
wait();
}
notifyAll(); //
}
Here, what I (unseccesfully try to) do is make a thread wait (in case a thread N helds the lock), once the thread N is done, in the run method i want to make the while condition true, so that all the threads waiting are notifie/awaken.
However, if I run it, a deadlock happens. I am just not able to awaken all the waiting threads! and the program cant finish.
I cant figure out how to solve this. I hope I am being clear enough.
UPLOAD
My solution, so far, using semaphores, as a poster suggested. I was stuck in this idea of using locks and monitors, etc. Semaphores look enough. It does the job, Suggestions very welcome.
#Override
public void run() {
//synchronization, if busy, show that the method is occupied and wait.
if (!semaphoreSinc.tryAcquire()) {
System.out.println(this.toString() + "waiting");
try {
semaphoreSinc.acquire();
} catch (InterruptedException ex) {
Logger.getLogger(Socio.class.getName()).log(Level.SEVERE, null, ex);
}
}
//mutex to prevent race condition
try {
mutex.acquire();
} catch (InterruptedException ex) {
Logger.getLogger(Socio.class.getName()).log(Level.SEVERE, null, ex);
}
methodRaceCondition(this);
//done, let other possible threads access it
mutex.release();
//awaken waiting threads
semaphoreSinc.release();
}
QUESTION:
Would it be possible to replicate this behaviour with monitors?

thread is not interruptible

I'm trying to work on the famous dining philosophers and its quite finished but I'm having a quite hard time trying to interrupt threads.
so as you know in this problem we have 5 threads (philosophers) and the user set an experiment time at which the experiment will end.
worth noticing that I looked multiple answers on StackOverflow.
The first one is from #Konrad Reiche How do you kill a Thread in Java?
/Stackoverflow link
In that particular post, people have stated that using volatile boolean as a flag might work out but I'm afraid that it is stated in the exercise paper that I cant use the volatile boolean to interrupt a thread but I can use it for other purposes. (studying exercise).
The second one is Thread interrupt() does not interrupt thread/Stackoverflow link
yet nothing really helped!.
I will try to provide the necessary code and I hope someone would just point out my mistake/s.
the class Philosopher is public and extends Thread!.
1)First attempt:(might get rejected by the professor if he doesn't want us to use volatile boolean as flag!)
when using volatile boolean like this it works:
private volatile boolean isNotStopped=true;
#Override
public void stopPhilosopher() {
System.out.printf("\n%s will stop.\n",selfPhilosopher.getName());
selfPhilosopher.interrupt();
isNotStopped=false;
}
#Override
public void run() {
while (isNotStopped){//selfPhilosopher is a thread equals to this!.
try {
think();
eat();
} catch (InterruptedException e) {//somehow this was never triggered!.
System.out.printf("%s was interrupted.\n",selfPhilosopher.getName());
}finally {//in the finally block i always get RUNNER, FALSE
System.out.printf("the %s is %s and is interrupted %b.\n", selfPhilosopher.getName(),selfPhilosopher.getState(), selfPhilosopher.isInterrupted());
}
}
}
[UPDATE] on Second attempt:[WORKING]
replacing selfPhilosopher.isInterrupted() with Thread.currentThread().isInterrupted() didn't make any difference as selfPhilosopher=this;
yet I was getting "will stop" from the stopPhilosopher() method but the threads seem to be like zombies keep coming back to life :(
due to the fact that I'm pretty convinced by the opinion of #Konrad Reiche from the first reference provided and the answer of #Nathan Hughes I will stick with using the boolean flag provided by the java isInterrupted() instead of using a volatile flag.
#Override
public void stopPhilosopher() {
System.out.printf("\n%s will stop.\n",selfPhilosopher.getName());
selfPhilosopher.interrupt();
}
#Override
public void run() {
while (!selfPhilosopher.isInterrupted()){//selfPhilosopher is a thread equals to this!.
try {
think();
eat();
} catch (InterruptedException e) {//somehow this was never triggered!.Now it works.
System.out.printf("%s was interrupted from catch clause!..\n",selfPhilosopher.getName());
selfPhilosopher.interrupt();
}
}
}
OUTPUT:
Philosopher2 in seat nr: 2 was interrupted from catch clause!..
When an InterruptedException is thrown, the interrupt flag is cleared. That means the next check your loop makes will indicate the thread is not interrupted and the thread will keep on running. That's what you're seeing when your finally block prints out false for the interrupt flag.
This is described in the API doc for the sleep method:
InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
Add this line to the block where you catch an InterruptedException:
Thread.currentThread().interrupt(); // restores interrupt flag
First of all: I favour the volatile boolean flag over isInterrupted(). It is clear, concise and idiomatically established. The necessary structure for isInterrupted() depends more on details (e.g. try/catch in your case because there seems to be a Thread.sleep (or something similar) declaring InterruptedException).
Since try/catch InterruptedException in your example is within the while-loop the interrupt is consumed and need to be resend to selfPhilosopher (which looks a bit dubious). To avoid this put the while-loop into a surrounding try-catch:
try {
while (!selfPhilosopher.isInterrupted()) {
think();
eat();
}
} catch (InterruptedException e) {
System.out.printf("%s was interrupted from catch clause!..\n",selfPhilosopher.getName());
// not necessary anymore: selfPhilosopher.interrupt();
}
The volatile boolean flag would not need resending and could be used in both constellations (while surrounding try/catch as well as while within try).
Additionally: Suppose your class implements Runnable and is not extending Thread then you also need to take care of setting selfPhilosopher at the beginning of run (and nowhere else).

Java Thread seemingly skipping conditional statement [duplicate]

This question already has answers here:
Why doesnt this Java loop in a thread work?
(4 answers)
Closed 3 years ago.
For a recent library I'm writing, I wrote a thread which loops indefinitely. In this loop, I start with a conditional statement checking a property on the threaded object. However it seems that whatever initial value the property has, will be what it returns even after being updated.
Unless I do some kind of interruption such as Thread.sleep or a print statement.
I'm not really sure how to ask the question unfortunately. Otherwise I would be looking in the Java documentation. I have boiled down the code to a minimal example that explains the problem in simple terms.
public class App {
public static void main(String[] args) {
App app = new App();
}
class Test implements Runnable {
public boolean flag = false;
public void run() {
while(true) {
// try {
// Thread.sleep(1);
// } catch (InterruptedException e) {}
if (this.flag) {
System.out.println("True");
}
}
}
}
public App() {
Test t = new Test();
Thread thread = new Thread(t);
System.out.println("Starting thread");
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
t.flag = true;
System.out.println("New flag value: " + t.flag);
}
}
Now, I would presume that after we change the value of the flag property on the running thread, we would immediately see the masses of 'True' spitting out to the terminal. However, we don't..
If I un-comment the Thread.sleep lines inside the thread loop, the program works as expected and we see the many lines of 'True' being printed after we change the value in the App object. As an addition, any print method in place of the Thread.sleep also works, but some simple assignment code does not. I assume this is because it is pulled out as un-used code at compile time.
So, my question is really: Why do I have to use some kind of interruption to get the thread to check conditions correctly?
So, my question is really: Why do I have to use some kind of interruption to get the thread to check conditions correctly?
Well you don't have to. There are at least two ways to implement this particular example without using "interruption".
If you declare flag to be volatile, then it will work.
It will also work if you declare flag to be private, write synchronized getter and setter methods, and use those for all accesses.
public class App {
public static void main(String[] args) {
App app = new App();
}
class Test implements Runnable {
private boolean flag = false;
public synchronized boolean getFlag() {
return this.flag;
}
public synchronized void setFlag(boolean flag) {
return this.flag = flag;
}
public void run() {
while(true) {
if (this.getFlag()) { // Must use the getter here too!
System.out.println("True");
}
}
}
}
public App() {
Test t = new Test();
Thread thread = new Thread(t);
System.out.println("Starting thread");
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
t.setFlag(true);
System.out.println("New flag value: " + t.getFlag());
}
But why do you need to do this?
Because unless you use either a volatile or synchronized (and you use synchronized correctly) then one thread is not guaranteed to see memory changes made by another thread.
In your example, the child thread does not see the up-to-date value of flag. (It is not that the conditions themselves are incorrect or "don't work". They are actually getting stale inputs. This is "garbage in, garbage out".)
The Java Language Specification sets out precisely the conditions under which one thread is guaranteed to see (previous) writes made by another thread. This part of the spec is called the Java Memory Model, and it is in JLS 17.4. There is a more easy to understand explanation in Java Concurrency in Practice by Brian Goetz et al.
Note that the unexpected behavior could be due to the JIT deciding to keep the flag in a register. It could also be that the JIT compiler has decided it does not need force memory cache write-through, etcetera. (The JIT compiler doesn't want to force write-through on every memory write to every field. That would be a major performance hit on multi-core systems ... which most modern machines are.)
The Java interruption mechanism is yet another way to deal with this. You don't need any synchronization because the method calls that. In addition, interruption will work when the thread you are trying to interrupt is currently waiting or blocked on an interruptible operation; e.g. in an Object::wait call.
Because the variable is not modified in that thread, the JVM is free to effectively optimize the check away. To force an actual check, use the volatile keyword:
public volatile boolean flag = false;

How can I wrap a method so that I can kill its execution if it exceeds a specified timeout?

I have a method that I would like to call. However, I'm looking for a clean, simple way to kill it or force it to return if it is taking too long to execute.
I'm using Java.
to illustrate:
logger.info("sequentially executing all batches...");
for (TestExecutor executor : builder.getExecutors()) {
logger.info("executing batch...");
executor.execute();
}
I figure the TestExecutor class should implement Callable and continue in that direction.
But all i want to be able to do is stop executor.execute() if it's taking too long.
Suggestions...?
EDIT
Many of the suggestions received assume that the method being executed that takes a long time contains some kind of loop and that a variable could periodically be checked.
However, this is not the case. So something that won't necessarily be clean and that will just stop the execution whereever it is is acceptable.
You should take a look at these classes :
FutureTask, Callable, Executors
Here is an example :
public class TimeoutExample {
public static Object myMethod() {
// does your thing and taking a long time to execute
return someResult;
}
public static void main(final String[] args) {
Callable<Object> callable = new Callable<Object>() {
public Object call() throws Exception {
return myMethod();
}
};
ExecutorService executorService = Executors.newCachedThreadPool();
Future<Object> task = executorService.submit(callable);
try {
// ok, wait for 30 seconds max
Object result = task.get(30, TimeUnit.SECONDS);
System.out.println("Finished with result: " + result);
} catch (ExecutionException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
System.out.println("timeout...");
} catch (InterruptedException e) {
System.out.println("interrupted");
}
}
}
Java's interruption mechanism is intended for this kind of scenario. If the method that you wish to abort is executing a loop, just have it check the thread's interrupted status on every iteration. If it's interrupted, throw an InterruptedException.
Then, when you want to abort, you just have to invoke interrupt on the appropriate thread.
Alternatively, you can use the approach Sun suggest as an alternative to the deprecated stop method. This doesn't involve throwing any exceptions, the method would just return normally.
I'm assuming the use of multiple threads in the following statements.
I've done some reading in this area and most authors say that it's a bad idea to kill another thread.
If the function that you want to kill can be designed to periodically check a variable or synchronization primitive, and then terminate cleanly if that variable or synchronization primitive is set, that would be pretty clean. Then some sort of monitor thread can sleep for a number of milliseconds and then set the variable or synchronization primitive.
Really, you can't... The only way to do it is to either use thread.stop, agree on a 'cooperative' method (e.g. occassionally check for Thread.isInterrupted or call a method which throws an InterruptedException, e.g. Thread.sleep()), or somehow invoke the method in another JVM entirely.
For certain kinds of tests, calling stop() is okay, but it will probably damage the state of your test suite, so you'll have to relaunch the JVM after each call to stop() if you want to avoid interaction effects.
For a good description of how to implement the cooperative approach, check out Sun's FAQ on the deprecated Thread methods.
For an example of this approach in real life, Eclipse RCP's Job API's 'IProgressMonitor' object allows some management service to signal sub-processes (via the 'cancel' method) that they should stop. Of course, that relies on the methods to actually check the isCancelled method regularly, which they often fail to do.
A hybrid approach might be to ask the thread nicely with interrupt, then insist a couple of seconds later with stop. Again, you shouldn't use stop in production code, but it might be fine in this case, esp. if you exit the JVM soon after.
To test this approach, I wrote a simple harness, which takes a runnable and tries to execute it. Feel free to comment/edit.
public void testStop(Runnable r) {
Thread t = new Thread(r);
t.start();
try {
t.join(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (!t.isAlive()) {
System.err.println("Finished on time.");
return;
}
try {
t.interrupt();
t.join(2000);
if (!t.isAlive()) {
System.err.println("cooperative stop");
return;
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.err.println("non-cooperative stop");
StackTraceElement[] trace = Thread.getAllStackTraces().get(t);
if (null != trace) {
Throwable temp = new Throwable();
temp.setStackTrace(trace);
temp.printStackTrace();
}
t.stop();
System.err.println("stopped non-cooperative thread");
}
To test it, I wrote two competing infinite loops, one cooperative, and one that never checks its thread's interrupted bit.
public void cooperative() {
try {
for (;;) {
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.err.println("cooperative() interrupted");
} finally {
System.err.println("cooperative() finally");
}
}
public void noncooperative() {
try {
for (;;) {
Thread.yield();
}
} finally {
System.err.println("noncooperative() finally");
}
}
Finally, I wrote the tests (JUnit 4) to exercise them:
#Test
public void testStopCooperative() {
testStop(new Runnable() {
#Override
public void run() {
cooperative();
}
});
}
#Test
public void testStopNoncooperative() {
testStop(new Runnable() {
#Override
public void run() {
noncooperative();
}
});
}
I had never used Thread.stop() before, so I was unaware of its operation. It works by throwing a ThreadDeath object from whereever the target thread is currently running. This extends Error. So, while it doesn't always work cleanly, it will usually leave simple programs with a fairly reasonable program state. For example, any finally blocks are called. If you wanted to be a real jerk, you could catch ThreadDeath (or Error), and keep running, anyway!
If nothing else, this really makes me wish more code followed the IProgressMonitor approach - adding another parameter to methods that might take a while, and encouraging the implementor of the method to occasionally poll the Monitor object to see if the user wants the system to give up. I'll try to follow this pattern in the future, especially methods that might be interactive. Of course, you don't necessarily know in advance which methods will be used this way, but that is what Profilers are for, I guess.
As for the 'start another JVM entirely' method, that will take more work. I don't know if anyone has written a delegating class loader, or if one is included in the JVM, but that would be required for this approach.
Nobody answered it directly, so here's the closest thing i can give you in a short amount of psuedo code:
wrap the method in a runnable/callable. The method itself is going to have to check for interrupted status if you want it to stop (for example, if this method is a loop, inside the loop check for Thread.currentThread().isInterrupted and if so, stop the loop (don't check on every iteration though, or you'll just slow stuff down.
in the wrapping method, use thread.join(timeout) to wait the time you want to let the method run. or, inside a loop there, call join repeatedly with a smaller timeout if you need to do other things while waiting. if the method doesn't finish, after joining, use the above recommendations for aborting fast/clean.
so code wise, old code:
void myMethod()
{
methodTakingAllTheTime();
}
new code:
void myMethod()
{
Thread t = new Thread(new Runnable()
{
public void run()
{
methodTakingAllTheTime(); // modify the internals of this method to check for interruption
}
});
t.join(5000); // 5 seconds
t.interrupt();
}
but again, for this to work well, you'll still have to modify methodTakingAllTheTime or that thread will just continue to run after you've called interrupt.
The correct answer is, I believe, to create a Runnable to execute the sub-program, and run this in a separate Thread. THe Runnable may be a FutureTask, which you can run with a timeout ("get" method). If it times out, you'll get a TimeoutException, in which I suggest you
call thread.interrupt() to attempt to end it in a semi-cooperative manner (many library calls seem to be sensitive to this, so it will probably work)
wait a little (Thread.sleep(300))
and then, if the thread is still active (thread.isActive()), call thread.stop(). This is a deprecated method, but apparently the only game in town short of running a separate process with all that this entails.
In my application, where I run untrusted, uncooperative code written by my beginner students, I do the above, ensuring that the killed thread never has (write) access to any objects that survive its death. This includes the object that houses the called method, which is discarded if a timeout occurs. (I tell my students to avoid timeouts, because their agent will be disqualified.) I am unsure about memory leaks...
I distinguish between long runtimes (method terminates) and hard timeouts - the hard timeouts are longer and meant to catch the case when code does not terminate at all, as opposed to being slow.
From my research, Java does not seem to have a non-deprecated provision for running non-cooperative code, which, in a way, is a gaping hole in the security model. Either I can run foreign code and control the permissions it has (SecurityManager), or I cannot run foreign code, because it might end up taking up a whole CPU with no non-deprecated means to stop it.
double x = 2.0;
while(true) {x = x*x}; // do not terminate
System.out.print(x); // prevent optimization
I can think of a not so great way to do this. If you can detect when it is taking too much time, you can have the method check for a boolean in every step. Have the program change the value of the boolean tooMuchTime to true if it is taking too much time (I can't help with this). Then use something like this:
Method(){
//task1
if (tooMuchTime == true) return;
//task2
if (tooMuchTime == true) return;
//task3
if (tooMuchTime == true) return;
//task4
if (tooMuchTime == true) return;
//task5
if (tooMuchTime == true) return;
//final task
}

BlockingQueue: put() and isEmpty() do not work together?

I would like to have a SynchronousQueue where I insert elements from one thread with put(), so the input is blocked until the element is taken in another thread.
In the other thread I perform lots of calculations and from time to time want to check if an element is already available, and consume it. But it seems that isEmpty() always returns true, even if another thread is waiting at the put() call.
How on earth is this possible? Here is the sample code:
#Test
public void testQueue() throws InterruptedException {
final BlockingQueue<Integer> queue = new SynchronousQueue<Integer>();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
if (!queue.isEmpty()) {
try {
queue.take();
System.out.println("taken!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// do useful computations here (busy wait)
}
}
});
t.start();
queue.put(1234);
// this point is never reached!
System.out.println("hello");
}
EDIT: Neither isEmpty() nor peek() work, one has to use poll(). Thanks!
From http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/SynchronousQueue.html#put(E) :
isEmpty
public boolean isEmpty()
Always returns true. A SynchronousQueue has no internal capacity.
(haven't looked into this in great detail, but you might want to take a look at either poll or take instead)
In addition to Tim's answer - you are doing nothing in the consumer thread but continuously calling isEmpty() in a tight loop. Rather than asking the OS to not run it until there is something useful for it to do, the consumer thread is continuously busy. Even if isEmpty worked correctly, the producer thread would rarely get a chance to run.
You could (if isEmpty() did work, or you switched to using poll()) make the consumer sleep for a bit between tests when the queue is empty to give the producer a chance to run, or (preferably) just take out the isEmpty() test and let the thread block on the mutex inside the take() in a sensible manner instead of polling.
your code looks like you are trying to do a poll. why not just call the poll() method?

Categories