External call to synchronized function held/locked - java

The Following class DoStuff starts a thread and syncs to protect the listener object from being accessed when null.
Now when accessing the DoStuff class function setOnProgressListener() externally I'm having issues because the call is getting held for a long time before it exits the function call. I'm not sure why this happens? I seems as if the synchronization has queued up a lot of calls? Any input on this would help!
I'm essentially passing null to the listener because I no longer wish to get updated for this status. I do this as part of my process to kill the DoStuff Thread.
Thanks!
public class DoStuff extends Runnable
{
Object MUTEX = new Object();
private OnProgressListener mOnProgressListener = null;
public DoStuff()
{
new Thread(this).start();
}
public void setOnProgressListener( OnProgressListener onProgressListener )
{
synchronized (MUTEX)
{
mOnProgressListener = onProgressListener;
}
}
private void reportStatus( int statusId )
{
synchronized (MUTEX)
{
if (null != mOnStatusListener)
{
mOnStatusListener.setStatusMessage(new OnStatusEvent(this, statusId));
}
}
}
// this is the run of a thread
public void run()
{
int status = 0;
do
{
// do some work and report the current work status
status = doWork();
reportStatus( status );
} while(true);
}
}

You should use wait/notify. here is sample;
public class DoStuff {
Object MUTEX = new Object();
String data = null;
public void setData(String data) {
synchronized (MUTEX) {
this.data = data;
System.out.println(Thread.currentThread());
MUTEX.notifyAll();
}
}
public void run() {
do {
synchronized (MUTEX) {
if (null == data) {
return;
} else {
System.out.println(data);
}
try {
MUTEX.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} while (true);
}
}

The trouble with this code is that your while() loop is constantly trying to grab the monitor for MUTEX immediately after releasing it or even yield()-ing to help the scheduler put another thread in. So there's a very good chance that anyone else trying to obtain that monitor will be starved, because your while() loop will consume most of your CPU time and even when other threads could run, they might not get the monitor they're waiting for.
Ideally a wait()/notify() pair should be used or failing that, you should at least call a Thread.yield() in your while loop, outside the synchronized block. (But I this second "solution" really isn't a very good one, you should consider using the first one instead.)
UPDATE: I read the code again and I think I believe to see what you wanted to achieve: printing the value of data every time you set a new value. If that's true, you should definitely go for the wait/notify solution, although if you want to absolutely guarantee that every single value is printed, you need to do even more work, possibly using a queue.

I'm a little confused about your code, can you provide the full listing?
First, where does DoStuff start a thread? Why are you quitting if your data is still null? (you might actually be out of the thread before setData even executes).
But the main thing here is that you're doing essentially a busy-waiting loop, in which you synchronize on the mutex. This is pretty wasteful and will generally block cores of your CPU.
Depending on what you are trying to do, you might want to use a wait-notify scheme, in which the thread goes to sleep until something happens.

Thanks all for your help. I was able to determine why the indefinite lock. Something important and obvious is that once I run the reportStatus() function call it will hold the lock MUTEX until it is completely done executing the callback. My fault was that at the registered callback I was calling setOnProgressListener(null) by mistake. Yes, I admit didn't post enough code, and most likely all of you would have catched the bug... So calling setOnProgressListener(null) would wait until the MUTEX object has been released, and the reportStatus() was held waiting to call setOnProgressListener(null), therefore I was in a deadlock!
Again the main point I learned is to remember that triggering a callback message will hold until the registered callback function is done processing it's call.
Thanks all!

Related

Understanding CompletableFuture simple implementation

Consider the following code taken from this article. It implements something similar to a CompletableFuture for learning purposes.
Here's the get() function of WaitingFuture:
#Override
public V get() throws ExecutionException {
this.thread = Thread.currentThread();
LockSupport.park(this);
if (throwable != null) {
throw new ExecutionException(throwable);
}
return result;
}
And here's the run() function of RunnableWaitingFuture:
#Override
public void run() {
try {
waitingFuture.result = userFunction.get();
} catch (Throwable throwable) {
waitingFuture.throwable = throwable;
} finally {
waitingFuture.finished = true;
LockSupport.unpark(waitingFuture.thread);
}
}
}
The Question:
It seems to me that if run() will finish before get() is even called then LockSupport.park(this); will be called after LockSupport.unpark(waitingFuture.thread), leaving the thread parking forever.
Is that true?
park()/unpark() is different to wait/notify, as the signal won’t be lost if unpark has been called before park().
However, it’s still only a single bit that doesn’t count how often unpark has been called, so it’s still wrong to assume that all calls will be perfectly paired.
Further, park will silently return on interrupts and is even allowed to return spuriously, which means for no reason.
In other words, even returning from park() doesn’t guaranty that the condition has been fulfilled. Just like with the other notification mechanisms, there is no way around using it in a loop.
The cited code is even worse, as it has another race condition regarding the thread variable. There is no guaranty that it has been written at the point where the other thread reads it for notifying it.
yes.
LockSupport.park(this);
should be replaced with something like
while (!waitingFuture.finished) {
LockSupport.park(this);
}
Generally, LockSupport.park is too low a feature, and Object::wait or Condition::await should be used instead for reliability.

How to terminate a task and continue the next one after a specified time limit? [duplicate]

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
}

Java Threading Cyclic Notify() and Wait()

I'm having a code in Java where two objects wait and notify each other when one finished processing. I'll keep my code simple with the following example and assuming there are no syntax error (I just want you to know the logic is more important here rather than the syntax).
Assuming I have object A which is a thread having this pseudo code
class A is Thread {
run() {
while(true) {
wait(); // wait for signal from B
// then do something if signal received
B.signal(); // let B know that we're done and wait again
}
}
}
Then we have here B which is also a thread having this pseudo code
class B is Thread {
run() {
while(true) {
// Do something
A.signal(); // Let A know to continue processing
wait(); // Wait for signal from A before doing something again
}
}
}
So as you can see there's a cycle. The problem is I am having a dead-lock and the reason here is because when A is finished processing, it signals B to work before it waits.. But by the time B is notified, there are chances that A still haven't reached the wait() code and B is already calling A.signal() and leads to a dead lock.
How do I properly solve this problem? The solution I have in mind is that when B is notified to work, I will let the thread of B sleep for a number of milliseconds but I don't think this is ever a good idea. Any help is appreciated, thanks in advance.
When you use notify() this should be associated with a state change.
When you use wait() this should be associated with a check for a state change.
In real code, you should only wait when you are waiting for something.
Note: wait() can wake spuriously, it doesn't mean notify() was called. As you noticed, notify() does nothing if nothing is wait()ing.
Instead of using this pattern, you can use a BlockingQueue to pass work/messages between threads. This has the wait/notify and the object containing work built in.
However, since you normally need a thread to do the work, there is an ExecutorService builtin to do this. This allows you to pass work to a pool of threads and collect the results.
In short, you should be using an ExecutorService.
If A is using the result of B, then maybe you can consider a BlockingQueue.
As you can find described in the Javadoc, you need to put your wait calls inside a loop that checks for a condition. Otherwise, if you don't have a condition variable or expression that you can check, it is possible that you miss the notify because you were not waiting at that point.
Also, as others have pointed out, you need to hold the monitor of the object you are calling the wait or notify method on; that's what the synchronized keyword is for.
In the below fix, the condition is very simple; it's a variable called notified in classes A and B.
Also, to get this right, A and B need to know about each other. In your code you seemed to be invoking static methods; but the notify method needs to be called on an instance, so you need to keep references to the instances of A and B in B and A, respectively.
This fixes the problems:
class A is Thread {
private B b;
private boolean notified;
public void run() {
while(true) {
synchronized(this) {
while (!notified) {
try {
wait(); // wait for signal from B
} catch (InterruptedException e) {}
}
notified = false;
}
synchronized(b) {
// then do something if signal received
b.notified = true;
b.notify(); // let B know that we're done and wait again
}
}
}
}
class B is Thread {
private A a;
private boolean notified;
public void run() {
while(true) {
synchronized(a) {
// Do something
a.notified = true;
a.notify(); // Let A know to continue processing
}
synchronized(this) {
while (!notified) {
try {
wait(); // Wait for signal from A before doing something again
} catch (InterruptedException e) {}
}
notified = false;
}
}
}
}

Waiting for an object to be initialized

I have an object that is being initialized in a separate thread. Initialization can take several seconds while a local DB is being populated.
SpecialAnalysis currentAnalysis = new SpecialAnalysis(params_here);
I'm trying to implement a "cancel" button, that sets the object's isCancelled boolean to true. What is the proper Java way to implement this?
while (currentAnalysis == null) {
}
currentAnalysis.cancel();
This method freezes the program as it appears to have entered a computationally inefficient loop. Is this a case where I could use Object.wait()?
My current bad/semi-successful solution is:
while (currentAnalysis == null) {
Thread.sleep(500);
}
currentAnalysis.cancel();
Thanks!
Firstly, yes Object.wait() and Object.notify() / Object.notifyAll() are what you need. Whether or not you use them directly is a different matter. Due to the ease of making mistakes programming directly with wait/notify it is generally recommended to use the concurrency tools added in Java 1.5 (see second approach below).
The traditional wait/notify approach:
Initialisation:
synchronized (lockObject) {
SpecialAnalysis currentAnalysis = new SpecialAnalysis(params_here);
lockObject.notifyAll();
}
In the 'cancel' thread:
synchronized (lockObject) {
while (currentAnalysis == null) {
try { lockObject.wait(); }
catch Exception(e) { } // FIXME: ignores exception
}
}
currentAnalysis.cancel();
Of course these could be synchronized methods instead of blocks. Your choice of lockObject will depend on how many 'cancel' threads you need etc. In theory it could be anything, i.e. Object lockObject = new Object(); as long as you are careful the correct threads have access to it.
Note that it is important to put the call to wait() in a while loop here due to the possibility of spurious wakeups coming from the underlying OS.
A simpler approach would be to use a CountDownLatch, sparing you from the nuts and bolts of wait()&notify():
(I'm making a couple of assumptions here in order to suggest a possibly cleaner approach).
class AnalysisInitialiser extends Thread {
private CountDownLatch cancelLatch = new CountDownLatch(1);
private SpecialAnalysis analysis = null;
#Override
public void run() {
analysis = new SpecialAnalysis(params);
cancelLatch.countDown();
}
public SpecialAnalysis getAnalysis() {
cancelLatch.await();
return analysis;
}
}
Then in the thread that needs to send the cancel signal: (obviously you need to get hold of the AnalysisInitialiser object in some way)
analysisInit.getAnalysis.cancel();
No concurrency primitive boilerplate, yay!
i like this question so voted up..
you can do like below
do {
if(currentAnalysis != null){
currentAnalysis.cancel();
}
}
while (currentAnalysis == null)
here your do keeps checking the value of currentAnalysis and once its not null then it performs cancel else keeps looping and checking currentAnalysis value.
this is one better approach i am finding right now

what does it mean when we say synchronized(instance field)..?

Attached the code..
what does this mean, synchronized(m)..?? why we should use that..??
What's the difference between synchronized(this) & synchronized(m)..??
class Waiter implements Runnable {
Message m;
public Waiter(Message m) {
this.m = m;
}
#Override
public void run() {
String name = Thread.currentThread().getName();
synchronized (m) {
try {
System.out.println("Waiting to get notified at time " +System.currentTimeMillis());
m.wait();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("Waiter thread notified at time "+System.currentTimeMillis());
System.out.println("Message processed ");
}
}
}
The difference between synchronized(this) and synchronized(m) is that by synchronizing on this, you synchronize on the entire instance. So, as you would expect, no body would be able to synchronize on this while you hold the lock.
public synchronized void foo() {
// Handle shared resource
}
is similar to
public void foo() {
synchronize(this) {
// Handle shared resource
}
}
By using objects, such as m, you get a more fine grained control over what you want to synchronize and when. But remember that if someone uses foo(), as shown above, it will not stop access to methods that are not synchronized on this:
public void anotherLock() {
synchronized(m) {
// Should handle another shared resource
// otherwise you might get unexpected results
}
}
While a thread is using foo(), another thread can access anotherLock().
The java keyword synchronized is used to synchronize different threads by one instance, acting as a mutual exclusive semaphore. Hence, the argument passed to synchronized is the instance which can be owned by one thread exclusively. It is up to you, the programmer, on which instance you like to synchronize your threads.
But it is a good idea to use the resource, which is under racing conditions, or the owning instance of that resource. The later you start a synchronized block and the earlier you leave it, the better your application will scale.
synchronized is used for thread safety. In your case it is used for implementing observer pattern. you want to wait for something to happen on Message object and then only process it so someone will notify on Message object m for which you are waiting (m.wait()).
When you wait on some object you need to take lock on that object for which you always need to put the wait() statement in a synchronized block on wait object. That is why you are using synchronized(m).
You can not replace it with synchronized(this) as you are calling wait() on object m so synchronized should be on m only.
Somewhere in your application you must be calling m.notify() or m.notifyAll() which will resume your wait() on m.

Categories

Resources