Java networking code executing before object received - java

I have a Java game that uses networking, and I have a client (using a Socket) fetching objects from an ObjectInputStream, running in its own thread.
From Client.java:
Object input = null;
while(true) {
input = in.readObject();
if(input != null) {
listener.gotObject(input);
}
}
This works pretty well. The object is gotten and is passed to the listener, which is a class linked to a my main GameApp class.
From the listener (NetControl.java):
public void gotObject(Object o) {
System.out.println(o);
app.gotObject(o);
}
"app" is the instance that handles all new objects received and deals with them.
From the app (GameApp.java) (edit: the non-abstract CardGameApp.java gives greater context):
public void gotObject(Object o) {
// select instance:
if(o instanceof GameList) {
GameList gameList = (GameList) o;
System.out.println("gamelist: " + gameList);
this.lobbyControl.gotGameList(gameList);
}
}
I've run this code in the debugger, one step at a time, and it works perfectly. When I run it normally though, I get a null pointer (output is as follows:)
Game ID: 0. Name: game1. Players: 1 / 1. // the object, as it is printed in Client.java
gamelist: Game ID: 0. Name: game1. Players: 1 / 1. // the object, as it is printed again in GameApp.java
Exception in thread "Thread-1" java.lang.NullPointerException
at com.lgposse.game.app.GameApp.gotObject(GameApp.java:61)
at com.lgposse.game.net.NetControl.gotObject(NetControl.java:47)
at com.lgposse.net.client.Client.run(Client.java:49)
Now, I see the object being printed twice, so I know it has been received... but I get a null pointer.
I added a sleep function in the middle of the function:
else if(o instanceof GameList) {
GameList gameList = (GameList) o;
System.out.println("gamelist: " + gameList);
try {
Thread.sleep(1000); // sleep 100 still gave null pointer
} catch (InterruptedException e) {}
this.lobbyControl.gotGameList(gameList);
}
And setting it to sleep for a while, it all finally worked.
Any idea why I need to sleep the thread like this? Is there something I should do differently? I'm not sure why I was able to print the object while it was still considered null.
Edit: added some more context.

It looks like lobbyControl is null, not gameList. If gameList were null, the top of the stack would be the gotGameList() method, not gotObject().
If sleeping helps the problem, then you must be manipulating the lobbyControl member without proper concurrency safeguards. An ObjectInputStream won't return an object until it's been fully read from the stream, so your problem has nothing to do with not having completely read the object.
Update: I can't follow all the code, but it appears that a reference to the object being constructed is leaked to a thread (the client in the NetControl), which is started before the constructor completes. If that is the case, that's very, very bad. You should never allow a partially constructed object to become visible to another thread.

Well, I'll start off by saying that the code snippets posted seem to help illustrate the issue, but i don't think the full picture is painted. I'd ask for a bit more code, to help get a full context.
That being said, I'd offer the following guidance:
Don't lean on java's built in object serialization. It's nice and
easy to use, but can be very unstable and error prone at runtime.
I'd suggest a custom object serialization and deserialization
scheme.
Depending on the scope of the game you're making, NIO may be a
netter choice. If you stick with regular IO, then make sure you
have a rock solid Thread Manager in place to properly handle the
threads dealing with the socket IO.
..without more code, that's the most I can offer.

Just to improve my comment...When i need to wait for one or more threads to finish, i like to use java.util.concurrent.CountDownLatch. Its very simple:
//game class
public class DummyGame
{
CountDownLatch signal;
public DummyGame( CountDownLatch signal)
{
this.signal = signal;
}
public void run()
{
doLogic();
signal.countDown();
}
}
//game controller class
public void run()
{
while (! gameOver)
{
CountDownLatch signal = new CountDownLatch(1); //wait one thread to finish
new thread(newGame(signal)).start();
//wait for game run() to finish
signal.await();
updateInterface();
}
}
That's just an idea, hope it helps.

Related

Java/JavaFX: Poll a database for single value update, while keeping responsiveness in GUI

Together with some friends, I've tried to create a turnbased game. We have some issues regarding checking for when a user has their turn, while also keeping the GUI responsive, and also closing the thread we're using now when the game is closed. I wish to get some information on how to do this, but I'm not sure whether the problem is JavaFX-related, thread-related or both.
I've tried to search as much as I can, but simply couldn't find exactly what I'm looking for, even though I believe it is quite simple. Right now, we have a thread running a loop when you click a button to check whether or not it is your turn. When it isn't your turn, we wish to disable some user input, so I'm not sure if we actually need a thread, other than to keep the responsiveness.
I've also tried implementing a class extending Thread, but this only seemed to make the problems worse by either starting a new thread each time it wasn't the players turn, or freezing the GUI if I put the loop outside of the thread.
public void refreshButtonPressed(){
try{
refreshButton.setDisable(true);
Thread pollThread = new Thread(() -> {
System.out.println("Thread started"); //Stop being able to start more threads
int user_id = 0;
String gamePin = "xxxxxx";
while (!GameConnection.yourTurn(user_id, Context.getContext().getGamePin())){ //This method checks the database if it is your turn
try{
Thread.sleep(5000); //So we don't flood the database
}
catch (InterruptedException e){
System.out.println("Interrupted");
break;
}
//If we close the game, stop the thread/while loop.
if (TurnPolling.closedGame){
break;
}
}
playerButton.setDisable(false);
refreshButton.setDisable(false);
refreshButton.setText("Refresh");
System.out.println("Thread ended");
});
pollThread.start();
}catch (Exception e){
e.printStackTrace();
}
}
And in the controller for the gameScreen.fxml file (Not the main screen, but one loaded via login screens and the Main extending Application).
public void initialize(URL location, ResourceBundle resources) {
playerButton.setDisable(!GameConnection.yourTurn(user_id, gameTurn));
myStage.setOnCloseRequest(event -> TurnPolling.closedGame = true);
}
Right now, the TurnPolling class only has the public static boolean closedGame, so as not to keep this in the controller. The last line setting the closedGame = true actually gives me a NullPointerException, which may be because the Stage isn't initialized yet, when I do this in the initialize() method?
I would wish to enable the players buttons only when it is their turn, as well as closing the thread (if needed) when the gameScreen closes. Right now, you have to click a button to check if it is your turn, which again checks every five seconds, and it won't stop when you close the game.`
Please tell me if you need more code or clarification, this is my first big project, so I don't really know how much to put here. I know this isn't working code, but it's as much as I can do without it feeling like cluttering. Thank you for any answers!
First, it is important to remember that it is not permitted to alter JavaFX nodes in any thread other than the JavaFX application thread. So, your thread would need to move these lines:
playerButton.setDisable(false);
refreshButton.setDisable(false);
refreshButton.setText("Refresh");
into a Runnable which is passed to Platform.runLater:
Platform.runLater(() -> {
playerButton.setDisable(false);
refreshButton.setDisable(false);
refreshButton.setText("Refresh");
});
Note that changes to your TurnPolling.closedGame field in one thread may not be visible in another thread, unless it’s declared volatile. From the Java Language Specification:
For example, in the following (broken) code fragment, assume that this.done is a non-volatile boolean field:
while (!this.done)
Thread.sleep(1000);
The compiler is free to read the field this.done just once, and reuse the cached value in each execution of the loop. This would mean that the loop would never terminate, even if another thread changed the value of this.done.
Using Task and Service
JavaFX provides a cleaner solution to all this: Task and Service.
A Service creates Tasks. A Service has a bindable value property, which is always equal to the value of the most recently created Task. You can bind your button properties to the Service’s value property:
int user_id = 0;
Service<Boolean> turnPollService = new Service<Boolean>() {
#Override
protected Task<Boolean> createTask() {
return new Task<Boolean>() {
#Override
protected Boolean call()
throws InterruptedException {
updateValue(true);
String gamePin = Context.getContext().getGamePin();
while (!GameConnection.yourTurn(user_id, gamePin)) {
Thread.sleep(5000);
if (TurnPolling.closedGame){
break;
}
}
return false;
}
};
}
};
playerButton.disableProperty().bind(turnPollService.valueProperty());
refreshButton.disableProperty().bind(turnPollService.valueProperty());
refreshButton.textProperty().bind(
Bindings.when(
turnPollService.valueProperty().isEqualTo(true))
.then("Waiting for your turn\u2026")
.otherwise("Refresh"));
When the player’s turn is finished, you would call turnPollService.restart();.
Whether you use a Service, or just use Platform.runLater, you still need to make TurnPolling.closedGame thread-safe, either by making it volatile, or by enclosing all accesses to it in synchronized blocks (or Lock guards).

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
}

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

Press and hold key programmatically java

Alright, I've searched now for a whole day, but no result. Maybe someone can help it.
I'm trying to generate a key "press and hold" situation in my java program, programmatically. Let me explain the situation:
I listen constantly for an event. Consider 2 events 'A' and 'B'. If event A occurs, I want to press and hold down the keyboard key (X), and if event 'B' occurs, I want to release the key (X). Now the main thing is, this all has to be a side process, so even if A occurs, I can listen for event B.
I've tried making a separate thread, making an infinite loop inside it, pressing the key using 'Robot' in java, but it turned out to be the most inefficient way of achieving this, as it consumes more than 60% of CPU. I've tried achieving this with a state changed, but don't seem to find a way to restrict the key press, to change only when I want it to.
I would appreciate a solution without any infinite loop, if possible, as I am already using 1 to listen for event occurrences. (Suggestions are welcome)
Here is my code for the thread:
public class KeyPress implements Runnable {
public String command;
public void run() {
try {
Robot r = new Robot();
while (true) {
//System.out.println(command);
if (command.equals("up")) {
r.keyPress(KeyEvent.VK_UP);
r.delay(20);
r.keyRelease(KeyEvent.VK_UP);
} else if (command.equals("finish")) {
break;
}
}
} catch (Exception e) {
System.out.println(e);
}
}
}
The instance of thread is created as usual, in my main class.
Also, if someone can explain this - when I remove or comment out the
System.out.println(command);
statement (as you see in the code), This thread stops working. If I add this, it works. Although this problem is secondary, as it still is a non-feasible solution.
Well, after a long and tiring attempt to solve this problem, I think I might have a solution.
Firstly, I create a thread everytime event 'A' occurs, although its the same as before. When event 'B' occurs, I interrupt the thread, which makes it to exit. Since these events 'A' and 'B' occur alternatively, this works for the CPU usage problem.
Another optimization, and possibly the answer to the problem of having to write print() statement, was I made the variable command as volatile. As explained here, the compiler optimization was most likely the problem I was facing.
Here is the code after these changes:
public class KeyPress implements Runnable {
public volatile String command;
public void run() {
try {
Robot r = new Robot();
while (command.equals("up") && !Thread.currentThread().isInterrupted()) {
r.keyPress(KeyEvent.VK_UP);
r.delay(20);
}
} catch (Exception e) {
System.out.println(e);
}
}
}
I hope this helps someone, and someone can provide suggestions on how to improve it.
Observer pattern maybe a good solution.
Do not loop in the thread. Use notify and listener mode like this:
Listen to the command:
class RobotObserver implements Observer{
private Robot r = new Robot();
#Override
public void update(Observable o, Object arg) {
String command=arg.toString();
if (command.equals("up")) {
r.keyPress(KeyEvent.VK_UP);
r.delay(20);
r.keyRelease(KeyEvent.VK_UP);
} else if (command.equals("finish")) {
System.out.println(command);
}
}
}
Notify listener:
Observable observable = new Observable();
observable.addObserver(new RobotObserver());
observable.notifyObservers("up");
observable.notifyObservers("finish");
PS: class Observer and Observable are both in package java.util.

External call to synchronized function held/locked

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!

Categories

Resources