I have a problem with Observer-Pattern and deadlock using threads.
package observerDeadLock;
import java.util.Observable;
public class MyModel extends Observable {
Integer foo;
public MyModel() {
foo = 0;
}
public void changeStatus(Integer newStatus) {
foo = newStatus;
notifyObservers(newStatus);
}
}
package observerDeadLock;
public class Job extends Thread {
public MyModel model;
public Job(MyModel model) {
super();
this.model = model;
}
public void run() {
prepareJob();
runMyJob();
}
private void runMyJob() {
// Some stuff
Integer choice = 1;
if (choice == 3) {
return;
}
else if (choice == 2) {
return;
}
else if (choice == 1) {
model.changeStatus(123); // Set a particalar status that MyController receive as wrong!
// PROBLEM: The Controller listen the changeStatus(123) of notifyObserver of MyModel and call a join() because I want the thread join and quit()
return; // <<- NEVER EXECUTED! join(timeout) isn't the solution IHMO...s
}
return;
}
private void prepareJob() {
// Do some stuff
}
}
package observerDeadLock;
import java.util.Observable;
import java.util.Observer;
public class MyController implements Observer {
private Job myJob;
private MyModel model;
public MyController() {
}
public void startJob() {
model = new MyModel();
model.addObserver(this);
myJob = new Job(model);
myJob.start();
}
#Override
public void update(Observable o, Object arg) {
if (o instanceof MyModel) {
if (((Integer) arg) == 1) {
// do other stuff
}
else if (((Integer) arg) == 2) {
// do other stuff
}
else if (((Integer) arg) == 123) { // 123 => Wrong state for myController, so must stop Job
// Stop myJob!!!
try {
//myJob.join(timeout); // isn' the solution IHMO
myJob.join(); // PROBLEM HERE!!! In job, the "return" statment is locked in changeStatus() -> myModel.notifyobserver() that lock here in JOIN();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
What I can do to resolve that problem? I suppose that use Thread.join() than Thread.interrupt() is a bad practice...
Suggestion?
Thanks!
You're apparently trying to join() the current thread (you can see this for yourself if you replace myJob.join() with System.out.println( Thread.currentThread() )), which isn't a very good idea, as the thread will be stuck forever, or until someone else interrupts it from the outside.
Instead of join(), just call interrupt(), there's nothing shameful about that. (Although whether it will have any effect depends on what else is in runMyJob())
Update: I can only assume that you edited out parts of your code for brevity, but if MyController really does nothing else if it encounters the exit value 123 than to stop the updating thread, then the whole construction is unnecessary. You should simply return from the runMyJob() method without setting anything and the thread will stop gracefully.
It looks like you have some logic errors here:
In runMyJob() you are calling model.changeStatus(123)
That calls notifyObservers() in Observable
That notifies the observers by calling MyController.update()
That then tries to join() on the thread.
Since the thread is the one that is calling the update() then it is trying to join with itself which obviously won't work. I'd have the main thread just do a join after the start:
myJob.start();
myJob.join();
You could also set some sort of value during the update (maybe a volatile int or AtomicInteger) that then can be read by the main thread.
If you edit your question to let us know what you are trying to accomplish, I'll adjust my answer to provide some better recommendations.
Related
This is a strange situation I've run into. I have an abstract base class that defines a protected field. There is also a public method that modifies the field. I then have some subclasses of the base class that make use of the field.
I've noticed that when I invoke the super-class method to modify the field, the change to the field's value does not seem to "carry through" to an instance of a subclass.
The other thing that needs to be mentioned is that the abstract class (and therefore its subclasses) implements Runnable. I wouldn't think that should have an effect on what I'm seeing, but multi-threading is not my forte.
Abstract base class:
public abstract class AbstractWidget implements Runnable {
// Other fields and methods omitted for brevity.
protected boolean running;
public void shutDown() {
running = false;
}
}
Subclass:
public class ConcreteWidget extends AbstractWidget {
// Other fields and methods omitted for brevity.
#Override
public void run() {
running = true;
while (running) {
// ...
}
logger.info("Shutting down");
}
}
So, when I finally invoke the shutDown() method, the subclass instance, running in a thread does not break from it's loop and return.
I've used the technique of modifying a boolean field from "the outside" to stop a "forever" thread many times before. I don't understand what's happening here.
UPDATE:
Below is an example of the code being called.
ConcreteWidget widet = new ConcreteWidget(...);
thread = new Thread(widget);
thread.start();
logger.info("Started");
...
logger.debug("shutting down");
widget.shutDown();
try {
logger.debug("doing join on thread");
thread.join();
logger.debug("returned from join");
} catch (InterruptedException e) {
logger.error("Exception", e);
}
The call to join() never returns.
UPDATE:
As requested I have included what I hope is a complete (enough) example of the code as I currently have it. NOTE: I have taken the suggestion and changed the protected boolean to AtomicBoolean.
public abstract class AbstractWidget implements Runnable {
protected final AtomicBoolean running = new AtomicBoolean(true);
public void shutDown() {
running.set(false);
}
}
public class ConcreteWidget extends AbstractWidget {
#Override
public void run() {
while (running.get()) {
// ... do stuff (including calling process() below)
}
}
private void process() {
try {
// ... do stuff
} catch (IOException e) {
logger.error("Exception", e);
running.set(false);
return;
}
}
}
In the "main" logic:
private void startService() {
widget = new ConcreteWidget(...);
thread = new Thread(widget);
thread.start();
logger.info("Started");
}
public void close() {
logger.debug("shutting down service");
widget.shutDown();
try {
logger.debug("doing join on service thread");
thread.join();
logger.debug("returned from join");
} catch (InterruptedException e) {
logger.error("Exception", e);
}
}
BTW, it still does not work.
Your problem is actually a simple one. By the time you call widget.shutDown();, the thread has not actually started, so when the thread actually starts, it sets running back to true, and never stops. Instead of using running to terminate the loop, use a separate stopped variable.
public abstract class AbstractWidget implements Runnable {
// Other fields and methods omitted for brevity.
private volatile boolean running = false;
private valatile boolean stopped = false;
public boolean isRunning() {
return running;
}
public boolean hasStopped() {
return stopped;
}
public void shutDown() {
stopped = true;
}
}
public class ConcreteWidget extends AbstractWidget {
// Other fields and methods omitted for brevity.
#Override
public void run() {
running = true;
while (!stopped) {
// ...
}
running = false;
logger.info("Shutting down");
}
}
With this setup, you might want to wait a while before stopping, if not the loop will never run at all.
ConcreteWidget widet = new ConcreteWidget(...);
thread = new Thread(widget);
thread.start();
logger.info("Started");
...
try {
Thread.sleep(500); // <--
} catch (Exception e) {}
logger.debug("shutting down");
widget.shutDown();
try {
logger.debug("doing join on thread");
thread.join();
logger.debug("returned from join");
} catch (InterruptedException e) {
logger.error("Exception", e);
}
Do you run widget.shutDown(); immediately after thread.start(); ?
maybe widget.shutDown(); has run before running = true; code inside run() method
[facepalm]
It turns out the problem was that the thread processing was hanging and never able to check the state of the running field. Once I corrected that problem, it worked just fine.
I did change my logic to use the AtomicBoolean instead of boolean, so thank you for that useful advice.
I have got a Class for a CustomView that has to inner Classes, both implement Runnable to do a Job in a separate Thread.
public class ValueSelector extends LinearLayout{
.....
private class AutoIncrementer implements Runnable {
#Override
public void run() {
if (plusButtonIsPressed) {
incrementValue();
mHandler.postDelayed(new AutoIncrementer(), REPEAT_INTERVAL_MS);
} else {
mHandler.removeCallbacks(this);
Thread.currentThread().interrupt();
}
}
}
private class AutoDecrementer implements Runnable {
#Override
public void run() {
if (minusButtonIsPressed) {
decrementValue();
mHandler.postDelayed(new AutoDecrementer(), REPEAT_INTERVAL_MS);
} else {
mHandler.removeCallbacks(this);
Thread.currentThread().interrupt();
}
}
}
}
How to clean them up properly?
Do they get Destroyed automatically when the Activity hosting those CustomViews gets destroyed?
Cheers
It will not get destroyed causing a memory leak, as your thread will have a strong reference to your view, and hence your activity.
Make the inner class static and hold weak reference to variables you need in run method.
Second thing you can do is interrupt your thread , when you view get detached from the window and have check in the run method if thread got interrupted or not, though not necessary if your thread is not doing too much work.
Here is what your runnable should look like
private static class AutoDecrementer implements Runnable {
AutoDecrementer (ValueSelector valueSelector ){
this.weakRef = new WeakReference<>(valueSelector);
}
#Override
public void run() {
ValueSelector valueSelector = (ValueSelector )weakRef.get();
if(valueSelector == null){
return ;
}
if (valueSelector.minusButtonIsPressed) {
valueSelector .decrementValue();
valueSelector .mHandler.postDelayed(new AutoDecrementer(), REPEAT_INTERVAL_MS);
} else {
valueSelector.mHandler.removeCallbacks(this);
Thread.currentThread().interrupt();
}
}
}
I have not checked for any errors.
No, it will cause error if Activity is destroyed while timer event is still pending. To avoied that, use WeakReference to some object, decrementing value.
But, generally it is bad practice - to mix UI and some ligic, because it is difficule to test. Consider using rxJava library, this will look like
Subscriptioin s = Observable.just(100, TimeUnit.Milliseconds)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.computation())
.subscribe(t -> decrementValue());
in your onPause() method cancel that actioin by
if (s != null && !s.inUnsubscribed()) {
s.unsubscribe();
s = null;
}
Basically, I have a class called Playback which extends a thread. I want to be able to run functions i have defined from this class from my thread object, but when i do they have no affect on the current thread of said object. I can only get my functions to work when called if i was .run() instead of .start() but that causes my GUI to freeze up. Here is my code
Playback function = new Playback(list, progBar, settings);
function.start();
function.terminate();
The above code does not work but the below does
Playback function = new Playback(list, progBar, settings);
function.run()
function.terminate();
When i use run though it causes my GUI to freeze. How do i call my methods on a already running thread?
here is my playback class:
package chronos.Functions;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.util.List;
import javafx.scene.control.ProgressBar;
import chronos.Graphics.InputValue;
public class Playback extends Thread {
List<InputValue> list;
ProgressBar progBar;
Settings settings;
boolean terminated = false;
public Playback(List<InputValue> list, ProgressBar progBar, Settings settings) {
this.list = list;
this.progBar = progBar;
this.settings = settings;
}
public void run() {
try {
Robot bot = new Robot();
double x = settings.getCycleNumbers();
Thread.sleep(settings.initialDelay);
for (double c = 0; c <= x; c++) {
if (terminated == false) {
System.out.println(terminated);
System.out.println(isInterrupted());
progBar.setProgress(c/x);
if (list.isEmpty() != true) {
for (InputValue i: list) {
if (terminated == false) {
if (i.getType() == "key") {
long longRuntime = System.currentTimeMillis();
if (settings.recDurations == true) {
if (i.getDuration() > 0) {
while(i.getDuration() > System.currentTimeMillis() - longRuntime ) {
bot.keyPress(i.getCode());
}
} else {
bot.keyPress(i.getCode());
}
} else {
if (settings.getDurationTime() > 0) {
while(settings.getDurationTime() > System.currentTimeMillis() - longRuntime ) {
bot.keyPress(i.getCode());
}
} else {
bot.keyPress(i.getCode());
}
}
} else {
bot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
if (settings.recDurations == true) {
Thread.sleep(i.getDuration());
} else {
Thread.sleep(settings.getDurationTime());
}
bot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
if (settings.recPositions == true) {
bot.mouseMove(i.getX(), i.getY());
}
}
if (settings.trackDelay == true) {
Thread.sleep(i.getDelay());
} else {
Thread.sleep(settings.getKeyDelay());
}
} else {
break;
}
Thread.sleep(settings.cycleDelay);
}
} else {
progBar.setProgress(0);
}
} else {
break;
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void terminate() {
System.out.println("terminated");
terminated = true;
}
}
How do i call my methods on a already running thread?
You can't.
A thread does what its run() method does. There is no way to change that. If you want a thread to do a certain thing, then you must create it with a run() method that does that thing.
Bear in mind, that there is no limit to what the run() method can do. For example, it might wait on a BlockingQueue, for "command" objects, and each time it gets a command, it might "perform" the command. I that case the run() method could do as many "different things" as you have different command objects that you can pass to it.
Your thread doesn't terminate because you don't properly synchronize access to the terminate variable: one thread modifies it, and the other one reads it.
If it's not at least volatile, the Java memory model doesn't guarantee that the modification made by one thread is visible from the other one.
So, either declare your variable volatile, or use an AtomicBoolean, or use the native mechanism allowing to interrupt threads: call thread.interrupt() to ask it to stop, and check for Thread.currentThread().isInterrupted() in the loop to check if the thread must stop.
The advantage of using interrupt is that the thread won't wait for sleep() to return before being able to stop. Instead, sleep() (and other blocking methods) will immediately throw an InterruptedException, signalling you that the thread has been asked to stop.
I have a generator class that owns a Thread in which a number of "records" to be generated is determined, then generates that many records (which get placed in a BlockingQueue for retrieval by another thread).
I'd like the other thread to know how many records are going to be generated (for sensible progress reporting among other things).
It seems Future gives me exactly the interface I'm after, but I'm new to Java, and not sure of the idiomatic way of implementing it.
My background is in C++/Win32, so I'd normally use a win32 "Event" (as created by CreateEvent(0, true, false, 0), with SetEvent and WaitForSingleObject for my signal and wait implementations). I've noticed Java has a CountDownLatch, but this somehow feels heavier than what I'm after (somewhat akin to using an int when I really want a boolean), and it seems unintuitive for this purpose (to me, anyway).
So here's my code using CountDownLatch and a Future. I've distilled my real code down a bit here (removed irrelevant implementation details and ignoring all error handling).
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
public abstract class Generator {
private CountDownLatch numRecordsSignal = new CountDownLatch(1);
private int numRecords;
private BlockingQueue<Record> queue = new LinkedBlockingQueue<Record>();
public Generator() {
new Thread(new Runnable() {
#Override
public void run() {
numRecords = calculateNumRecords();
numRecordsSignal.countDown();
for (Record r : generateRecords()) {
try {
queue.put(r);
} catch (InterruptedException e) {
// [ ... snip ... ]
}
}
}
}).start();
}
public Future<Integer> numRecords() {
return new Future<Integer>() {
// Ignore cancel for now (It wouldn't make sense to cancel
// just this part of the Generator's work, anyway).
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}
public Integer get() throws InterruptedException {
numRecordsSignal.await();
return numRecords;
}
public Integer get(long timeout, TimeUnit unit)
throws InterruptedException {
numRecordsSignal.await(timeout, unit);
return numRecords;
}
public boolean isCancelled() {
return false;
}
public boolean isDone() {
// Since we can't cancel, just check the state of the
// signal
return numRecordsSignal.getCount() == 0;
}
};
}
public Record nextRecord() throws InterruptedException {
return queue.take();
}
/** --- Boring stuff below this line --- */
public interface Record { }
protected abstract int calculateNumRecords();
protected abstract Iterable<Record> generateRecords();
}
Now for my actual questions:
Is there a better mechanism than CountDownLatch for single-shot signalling?
I want callers to be able to either wait or poll on the result, but don't need them to be able to cancel the operation. Is Future the right way to expose this stuff?
Does any of this stuff look particularly "un-Java"? Am I on the wrong track completely?
Edit:
Just to clarify, I expect the caller to be able to do the following:
Generator gen = new Generator();
Integer numRecords = gen.numRecords().get(); // This call might block waiting for the result
numRecords = gen.numRecords().get(); // This call will never block, as the result is already available.
It's just a slow-to-initialise value I'm trying to implement. Once the "initialised" condition is met, it should latch. The value doesn't get re-evaluated once it's known.
Side comment
You should not start a thread in a constructor - it is very conceivable that the Generator object is not fully created when the thread starts, and the countdown latch could well be null for example. You can create the thread in the constructor, but should start it in a seperate method. Your calling code would become:
Generator g = new Generator();
g.start();
Your question
You are reimplementing a Future yourself, which is not necessary nor desirable in my opinion. I would redesign the class and make Generator implement Callable<Integer> and run it through an executor. That provides you with several things:
remove the threading logic from the Generator, which enables you a more efficient management of your threads at a higher level in your call stack
the integer is returned via the future in your calling code and you rely on the JDK to handle the implementation
I have assumed that it's ok to first populate the queue then return the integer
you can call future.get() as many times as you want - it will only block the first time it is called.
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<Integer> future = executor.submit(new GeneratorImpl()); //a concrete implementation of Generator
int numRecords = 0;
try {
numRecords = future.get(); //you can use a get with timeout here
} catch (ExecutionException e) {
//an exception happened in Generator#call()
} catch (InterruptedException e) {
//handle it
}
//don't forget to call executor.shutdown() when you don't need it any longer
}
public abstract class Generator implements Callable<Integer> {
private BlockingQueue<Record> queue = new LinkedBlockingQueue<Record>();
#Override
public Integer call() {
int numRecords = calculateNumRecords();
for (Record r : generateRecords()) {
try {
queue.put(r);
} catch (InterruptedException e) {
// [ ... snip ... ]
}
}
return numRecords;
}
public Record nextRecord() throws InterruptedException {
return queue.take();
}
/**
* --- Boring stuff below this line ---
*/
public interface Record {
}
protected abstract int calculateNumRecords();
protected abstract Iterable<Record> generateRecords();
}
EDIT
If you need to return numRecods asap, you can populate your queue in a separate thread:
public Integer call() {
int numRecords = calculateNumRecords();
new Thread(new Runnable() {
#Override
public void run() {
for (Record r : generateRecords()) {
try {
queue.put(r);
} catch (InterruptedException e) {
// [ ... snip ... ]
}
}
}
}).start(); //returns immediately
return numRecords;
}
The standard Java equivalents of "WaitOnSingleEvent()" and "SetEvent()" for Java threads are "wait()", "notify()" and "notifyAll()".
After looking at implementing my own signal mechanism and following the bread-crumb trail left by others doing the same thing, I came across the javadoc for AbstractQueuedSynchronizer, which includes a code snippet for a "BooleanLatch", which perfectly meets my needs:
class BooleanLatch {
private static class Sync extends AbstractQueuedSynchronizer {
boolean isSignalled() { return getState() != 0; }
protected int tryAcquireShared(int ignore) {
return isSignalled()? 1 : -1;
}
protected boolean tryReleaseShared(int ignore) {
setState(1);
return true;
}
}
private final Sync sync = new Sync();
public boolean isSignalled() { return sync.isSignalled(); }
public void signal() { sync.releaseShared(1); }
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
}
Doing a bit more searching, I found that a number of frameworks include a BooleanLatch (Apache Qpid being one). Some implementations (such as Atlassian's), are auto-resetting, which would make them inappropriate for my needs.
Standard observer notification pattern can be helpful here, if i understood your problem correctly.
For one shot signalling in this scenario Semaphore is better as it remembers the "signal".
Condition object [wait() is on a condition] won't remember the signal.
Semaphore numRecordsUpdated = new Semaphore(0);
In Generator
numRecordsUpdated.release();
In consumer
numRecordsUpdated.acquire();
I have a thread inside a class like this-
import java.util.Observable;
public class Download extends Observable {
private int state = 0;
private final Thread myThread = new Thread(() -> {
/*
some work to do here
*/
setChanged();
notifyObservers(state);
});
public void download(int state) {
if (!myThread.isAlive()) {
this.state = state;
myThread.start();
}
}
public Thread getThread() {
return myThread;
}
public static void MyMethod() throws InterruptedException {
Download down = new Download();
down.addObserver((Observable ob, Object dat) -> {
System.out.println(ob);
if ((int) dat == 1) {
down.download(2);
} else {
System.out.println("success");
}
});
down.download(1);
down.getThread().join();
}
public static void main() throws InterruptedException {
MyMethod();
}
}
The problem is I never get it to print the "success" message.
I assume, it is because all observers are being notified from inside of MyThread. So when down.download(2) is called from the observer inside MyMethod(), the previous thread is still running and the call is ignored.
How can I notify all observers from the main thread, not from the myThread?
You are calling down.download(2) from within the execution of MyThread, therefore the thread is still alive which means that your download method does nothing because of if(!myThread.isAlive()).
I would recommend you to use the Executor framework and Listenable Futures from Guava instead of creating threads manually. Example code from the Guava wiki:
ListeningExecutorService service =
MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
ListenableFuture<Explosion> explosion = service.submit(new Callable<Explosion>() {
public Explosion call() {
return pushBigRedButton();
}
});
Futures.addCallback(explosion, new FutureCallback<Explosion>() {
// we want this handler to run immediately after we push the big red button!
public void onSuccess(Explosion explosion) {
walkAwayFrom(explosion);
}
public void onFailure(Throwable thrown) {
battleArchNemesis(); // escaped the explosion!
}
});
Note that Futures.addCallback(..) also has an overload which allows you to determine which executor should execute the callback, this seems to be what you want.