I have a daemon thread which is started when a page is opened. The thread is then stopped when the page is closed. So in my class which holds the thread, I have it created like this:
class A {
private static volatile boolean isStopped=false;
//this method is called then the page is loaded
public void testListener() {
Thread listener = new Thread(new Runnable() {
public void run() {
while(!isStopped) {
//perform listener event
try {
//after every event sleep for a while
Thread.sleep(1000 *2)
} catch(InterruptedException e){}
}
}
});
}
listener.setName("Test-Server-Daemon");
listener.setDaemon(true);
listener.start();
// reset back to false so thread can be restarted when the page load event,
// call this method instance
if (isStopped) {
isStopped=false;
}
}
/**This is called when page is closed**/
public static void stopListener() {
isStopped=true;
}
}
Upon investigation, I have noticed that when the page is closed and not opened again within say 30 seconds interval, the thread is gracefully stopped.
But when the page is closed and re-opened within say 2 seconds interval the old thread does not get stopped and hence runs simultaneously with a new one.
And so as you can see from below image, I have the same thread started again when I close and quickly open the page.
Do anyone knows how to prevent this from occurring?
I have tried using thread interrupt where I reset the mutex but no joy.
EDITED:
isStopped is volatile.
To follow on from #Jordão's answer, the isStopped variable should be per thread. I would recommend using something like an AtomicBoolean and changing your thread code to be approximately:
public AtomicBoolean testListener() {
final AtomicBoolean isStopped = new AtomicBoolean(false);
Thread listener = new Thread(new Runnable() {
public void run() {
while(!isStopped.get()) {
...
}
}
});
listener.setName("Test-Server-Daemon");
listener.setDaemon(true);
listener.start();
return isStopped;
}
Then back in your page controller you can do:
AtomicBoolean isStopped = testListener();
// do the page stuff
...
// when done stop the thread
isStopped.set(true);
You're probably overriding the value of isStopped with false before the old thread has a chance to see that it should stop. The problem is here:
if(isStopped)
{
isStopped=false;
}
You should better isolate your code: create separate instances of A for each thread and make isStopped an instance volatile field (not static). And remove that block of code...
If your flag isStopped is not true for at least 2 seconds, your thread could be sleeping when this happens. A much simpler solution is to avoid start/stopping the thread as this could cause as much overhead as it saves (it certainly complicates the issue)
This is what I would do is start the thread once and only once.
public void run() {
try {
while(true) {
if(!isStopped) {
//perform listener event
}
//after every event sleep for a while
Thread.sleep(1000 *2);
}
} catch(InterruptedException e){}
}
By setting the flag, it stops performing, but the thread keeps checking.
Try using AtomicBoolean instead of the Boolean field.
Use the compareAndSet method; let me know if u need more clarification as the javadocs are quite useful.
Try making isStopped volatile, i.e. private static volatile boolean isStopped=false;. There may be a lag in memory synchronization between the two threads (the main one and your own).
Move your instantiation outside of your method and make it static. This guarentee's you will only ever have one instance of this Thread.
private static Thread listener;
Once this is done you can add this to you're method:
if(listener.isAlive()) try { Thread.sleep(100); } catch (InterruptedException ie) {}
listener = new Thread(new Runnable() {
public void run() {
while(!isStopped) {
//perform listener event
try {
//after every event sleep for a while
Thread.sleep(1000 *2)
}
catch(InterruptedException e){}
}
}
});
Now you won't start a new thread until the previous one has stopped.
(NB, not sure if isAlive() is accurate, you may need to create your own Thread implementation to accurately reflect if the thread is stopped if it isn't)
I would used a java.util.concurrent.ScheduledExecutorService for that. It will manage the thread and the scheduling of the task.
For instance:
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class Scheduler {
static ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
static ScheduledFuture<?> future;
// called when the page is opened
public static void open() {
future = service.scheduleAtFixedRate(new Runnable() {
public void run() {
//perform listener event
}
}, 0, 2, TimeUnit.SECONDS); // every 2 seconds
}
// called when the page is closed
public static void close() {
// stop listener event
future.cancel(true);
future = null;
}
}
Related
I have the following method, that called every time I click over a button, this results to start a new thread again and again when the button is pressed, that results to multiple initialisation of thread, however I want only one thread should get executed, how can I achieve this.
private void scheduleMessages() {
new Thread(new Runnable() {
#Override
public void run() {
//Some operations
}
}).start();
}
Note: this is a small method and I don't want to create a separate class, just to make it singleton, so a solution without singleton pattern will be appreciated.
if you cannot make instance of this to check isActive() you should make a semaphore variable - a boolean, that you set to true when you start thread and set to false when you are done.
private void scheduleMessages() {
if (!taskRunning){
new Thread(new Runnable() {
#Override
public void run() {
taskRunning = true;
//Some operations
taskRunning = false;
}
}).start();
}
}
Have that thread be a background thread - maybe initialize it when the button is pressed the first time.
Have that thread listen to a queue - and act upon messages in that queue.
Whenever the button is pressed again, put a new message into the queue.
If your need to execute every requests but on a specific number of threads, you can use a thread pool and let the executor manage the queue .
private ExecutorService services;
private final static int POOL_SIZE = 1;
public MessagesService(){
services = Executors.newFixedThreadPool(POOL_SIZE);
}
public void scheduleMessages(Runnable r){
services.submit(r);
}
If you call addCall x times, x thread will be executed at the end but will never use more than the number of thread available in the pool. Here, 1 thread.
For a system that only accept one request, you can use the same approch but check the Future returned by a single thread executor. That way, you can check the status of the service.
private ExecutorService services;
private Future<?> lastCall;
public MessagesService() {
services = Executors.newSingleThreadExecutor();
lastCall = null;
}
public synchronized void scheduleMessages(Runnable r) {
if(!isScheduled()){
lastCall = services.submit(r);
}
}
public boolean isScheduled(){
return lastCall != null && !lastCall.isDone();
}
That way, the Runnable doesn't need to update a flag, which give a reusable solution.
Here is a sample of the Runnable to test these codes :
new Runnable() {
System.out.println("Running");
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
}
I state that I read about thread, but I've never used.
So I ask to you :)
I have two thread: A and B,
where A manages the GUI, and B manages the logic.
I would start with A.
Then when A draw the GUI, I would pause it, to wait B that reach a point X into run method.
And when B reach the X point into run method, I pause B, and resume A.
A and B share some variable to manage the GUI, and the logic...
Can I do it? if yes, how? :)
Using wait() and notify() methods:
wait() - Causes the current thread to wait until another thread invokes the
notify() method or the notifyAll() method for this object.
notify() - Wakes up a single thread that is waiting on this object's monitor.
You can block threads using the wait and notify methods of the Object class, but it can be tricky to get right. Here's an example inside an infinite loop in a Runnable:
public class Example implements Runnable {
private volatile boolean running = true;
private volatile boolean paused = false;
private final Object pauseLock = new Object();
#Override
public void run() {
while (running) {
synchronized (pauseLock) {
if (!running) { // may have changed while waiting to
// synchronize on pauseLock
break;
}
if (paused) {
try {
pauseLock.wait(); // will cause this Thread to block until
// another thread calls pauseLock.notifyAll()
// Note that calling wait() will
// relinquish the synchronized lock that this
// thread holds on pauseLock so another thread
// can acquire the lock to call notifyAll()
// (link with explanation below this code)
} catch (InterruptedException ex) {
break;
}
if (!running) { // running might have changed since we paused
break;
}
}
}
// Your code here
}
}
public void stop() {
running = false;
// you might also want to interrupt() the Thread that is
// running this Runnable, too, or perhaps call:
resume();
// to unblock
}
public void pause() {
// you may want to throw an IllegalStateException if !running
paused = true;
}
public void resume() {
synchronized (pauseLock) {
paused = false;
pauseLock.notifyAll(); // Unblocks thread
}
}
};
(For more information on why we need to synchronize as illustrated above whilst calling wait and notifyAll, see the Java tutorial on the subject.)
If another Thread calls this Runnable's pause() method, then the Thread running the runnable will block when it gets to the top of the while loop.
Note that it is not possible to pause a thread at any arbitrary point. You need the Thread to periodically check whether it should pause and block itself if so.
I would expect that you don't need to pause the GUI thread. The operating system will take care of that, and it needs to be ready to respond in case the user does something.
One other thought is to make sure the shared variables are properly synchronized between the two threads. I tried answering a question relating to that recently, see here.
you can use a CountDownLatch. When Thread A has to wait for Thread B will call countDownLatchInstance.await(); When B reach the X point will invoke countDownLatchInstance.countDown(); allowing A to continue its execution flow.
When you say
A manages the GUI
I hope you do not refer to the UI/Main Thread
,
public class Mutex {
private final AtomicBoolean lock;
private final Object mutex;
public Mutex(boolean lock) {
this.lock = new AtomicBoolean(lock);
this.mutex = new Object();
}
public void step() {
if (lock.get()) synchronized(mutex) {
try {
mutex.wait();
} catch (InterruptedException ex) {}
}
}
public void lock() {
lock.set(true);
}
public void unlock() {
lock.set(false);
synchronized(mutex) {
mutex.notify();
}
}
}
Just add Mutex object to your thread and make getter.
public class MyThread extends Thread {
private final Mutex mutex;
public MyThread() {
this.mutex = new Mutex(false);
}
public Mutex getMutex() {
return this.mutex;
}
#Override
public void run() {
while (!isInterrupted()) {
mutex.step();
// do your code
}
}
}
If you want to pause the thread just call
myThread.getMutex().lock();
If you want to resume the thread just call
myThread.getMutex().unlock();
That's the way I got thread's wait and notify working for me:
public class Main {
public static void main(String[] args) {
final Object lock = new Object();
MyThread t = new MyThread();
t.lock = lock;
t.run();
while (true) {
try {
synchronized (lock) {
lock.wait();
}
System.out.println("hello");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class MyThread extends Thread {
Object lock;
#Override
public void run() {
JFrame fr = new JFrame("Anothing");
JButton btn = new JButton("Next");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
synchronized (lock) {
lock.notify();
}
}
});
fr.setLayout(new FlowLayout());
fr.add(btn);
fr.setSize(400, 400);
fr.setVisible(true);
}
}
Then, whenever I press the button, the other thread wakes up, executes one round and waits for a new clicking.
The java primitive to suspend and resume a thread is deprecated. See this to figure how you can achieve best what you need - http://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
Check how you can do the equivalent of suspend & resume
What should I use instead of Thread.suspend and Thread.resume?
As with Thread.stop, the prudent approach is to have the "target thread" poll a variable indicating the desired state of the thread (active or suspended). When the desired state is suspended, the thread waits using Object.wait. When the thread is resumed, the target thread is notified using Object.notify.
Example code is given in the same answer to help you achieve this.
Hello i'm new in Android(Java), and i have a problem with the use of thread
I define e new Thread timed (every 5 seconds) inside a class of my android Project.
The "mContinueThread" variable is used to cicle every 5 seconds
r = new Runnable() {
public void run() {
while (mContinueThread) {
try {
Thread.sleep(MILLISEC_BEFORE_RELOAD);
mHandler.sendEmptyMessage(GET_TRACKING);
}
catch (Exception e)
{
}
}
}
};
t = new Thread(r);
In the CLass there is a method StartTrack() that starts with Thread
public void StartTrack()
{
mContinueThread=true;
if (!mThreadIsStarted)
{
mThreadIsStarted=true;
t.start();
}
else
{
}
}
and there is also a method Logout that stop the thread, using the "mContinueThread" variable:
public void LogOut()
{
//STOP THREAD
mContinueThread=false;
....
}
If in the class Logout() method is executed the thread is stopped, but if the StartTrack() method is called again I don't know how to restart the execution of the thread.
Can you Help Me?
You can use AsyncTask in Android. This will get rid of the burden of managing the threads manually. Please visit http://developer.android.com/reference/android/os/AsyncTask.html
You cannot re-start a thread. Once thread is finished execution it will reach the DEAD state. And whatever is DEAD cannot be brought back to life again, neither in real world nor in JAVA world.
You have no way to restart a thread as long as it exited. You can just start a new start.
I solved so:
In my class I just define the Runnable object, but not the new Thread.
In the StartTrack method(), if the thread has not yet been instantiated, I create and start
public void StartTrack()
{
mContinueThread=true;
if (!mThreadIsStarted)
{
mThreadIsStarted=true;
t = new Thread(r);
t.start();
}
}
In the "LogOut()" method, if Thread is started, I Stop It, and I set It to Null.
In this way, at the next call of "StartTrack()" method, I can recreate it again
public void LogOut()
{
mContinueThread=false;
if (mThreadIsStarted)
{
//THREAD STOP
mContinueThread=false;
mThreadIsStarted=false;
//THREAD TO NULL
t=null;
}
...
}
I suggest it's better to use something like Timer instead of thread.
http://developer.android.com/reference/java/util/Timer.html
Then you can do cancel() if you want to stop execution of your task
and resume it by scheduling new one.
Here's essentially my problem:
while (true) {
if (previous 'doWorkAsync' method is not still in flight) {
doWorkAsync() // this returns immediately
}
wait set amount of time
}
A couple solutions come to mind for me:
Block until doWorkAsync() completes. This is not desirable to me for a few reasons.
It (potentially) results in waiting longer than I really needed to in the 'wait some set amount of time' line (e.g. if doWorkAsync takes 5 seconds, and the set amount of waiting time is 10 seconds, this will result in 15 seconds of waiting between calls, which isn't what I wanted). Of course, I could account for this by waiting less time, but somehow it just feels clunky.
It also ties up this thread unnecessarily. Instead of waiting for this task to come back, this thread could handle other work, like making config updates so the next call to doWorkAsync() has fresh data.
Use a gating mechanism. The easiest implementation that comes to mind is a boolean, set before calls to doWorkAsync(), and unset when doWorkAsync() completes. This is essentially what I'm doing now, but I'm not sure if it's an anti-pattern??
Is #2 the right way to go, or are there better ways to solve this problem?
EDIT: If it helps, doWorkAsync() returns a ListenableFuture (of guava).
The original question may not have been 100% clear. Here's the crux. If the async request finishes before the given timeout, this code will always work. However, if the async task takes SET_AMOUNT_OF_TIME + epsilon to complete, then this code will sleep twice as long as necessary, which is what I'm trying to avoid.
The simplest way to do this is using the wait and notifyAll methods already in Java. All you need to do is use an AtomicBoolean as a flag and block on it until the another Thread tells you something has changed.
The difference between that and your approach is that a blocked thread doesn't do anything whereas a polling thread uses CPU time.
Here is a simple example using two Threads - the Runnable "First" is submitted and it waits on done until the Runnable "Second" notifies that it has changed the flag.
public class App {
private static final AtomicBoolean done = new AtomicBoolean(false);
private static final class First implements Runnable {
#Override
public void run() {
while (!done.get()) {
System.out.println("Waiting.");
synchronized (done) {
try {
done.wait();
} catch (InterruptedException ex) {
return;
}
}
}
System.out.println("Done!");
}
}
private static final class Second implements Runnable {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
return;
}
done.set(true);
synchronized (done) {
done.notifyAll();
}
}
}
public static void main(String[] args) throws InterruptedException {
final ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(new First());
Thread.sleep(1000);
executorService.submit(new Second());
executorService.shutdown();
}
}
The sleep calls are just to show that a task of arbitrary length can take place, obviously they are not required.
The thing to note is that First prints "waiting" every time it enters the loop and, if you run the code, it only prints it once. The second thing to note is that First reacts to the changing of the flag immediately as it is told to awake and recheck when the flag is changed.
I have used return in the InterruptedException blocks, you may want to used Thread.currentThread().interrupt() instead so that the process doesn't die if it's spuriously interrupted.
A more advanced approach is to use Lock and Condition
public class App {
private static final Lock lock = new ReentrantLock();
private static final Condition condition = lock.newCondition();
private static final class First implements Runnable {
#Override
public void run() {
lock.lock();
System.out.println("Waiting");
try {
condition.await();
} catch (InterruptedException ex) {
return;
} finally {
lock.unlock();
}
System.out.println("Done!");
}
}
private static final class Second implements Runnable {
#Override
public void run() {
lock.lock();
try {
Thread.sleep(1000);
condition.signalAll();
} catch (InterruptedException ex) {
return;
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) throws InterruptedException {
final ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(new First());
Thread.sleep(1000);
executorService.submit(new Second());
executorService.shutdown();
}
}
In this situation First acquires a lock on the Lock object the immediately calls await on the Condition. The releases the lock and blocks on the Condition.
Second then acquires a lock on the Lock and calls signalAll on the Condition which awakes First.
First then reacquires the lock and continues execution, printing "Done!".
EDIT
The OP would like to call the method doWorkAsync with a specified period, if the method takes less time than the period then the process has to wait. If the method takes longer then the method should be called again immediately after.
The task needs to be stopped after a certain time.
At no point should the method be running more than once simultaneously.
The easiest approach would be to call the method from a ScheduledExecutorService, the Runnable would wrap the method and call get on the Future - blocking the scheduled executor until it is done.
This guarantees that the method is called with at least WAIT_TIME_BETWEEN_CALLS_SECS delay.
Then schedule another task that kills the first one after a set time.
final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
final Future<?> taskHandle = scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
final ListenableFuture<Void> lf = doWorkAsync();
try {
doWorkAsync().get();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (ExecutionException ex) {
throw new RuntimeException(ex);
}
}
}, 0, WAIT_TIME_BETWEEN_CALLS_SECS, TimeUnit.SECONDS);
scheduledExecutorService.schedule(new Runnable() {
#Override
public void run() {
taskHandle.cancel(false);
}
}, TOTAL_TIME_SECS, TimeUnit.SECONDS);
The best solution would be call the raw Runnable on a ScheduledExecutorService rather than calling it on another executor and blocking on the ListenableFuture.
Think what you are looking for is The Reactor Pattern.
Is there a reason you don't want these things running at the same time? If what you want to do is chain them, you could use Futures. Akka has Composable Futures and mappable ones.
Hey guys
I am using runnable outside the oncreate in my android application where i have used thread to setprogress of ProgressBar. What i dont know is how to stop/destry the thread when stop button is pressed since thread.stop is not a method and how to resume from that , how to even destroy the thread.
I know i have to make some methods and members in runnable but i dont exactly know what??
Thread.stop() is no longer used since it was considered dangerous: http://download.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html.
You must let the thread come naturally to an end as a result of a variable change. The link also gives some advice about how to achieve this.
public class MyThread extends Thread {
private boolean threadDone = false;
public void done() {
threadDone = true;
}
public void run() {
while (!threadDone) {
// work here
// modify common data
}
}
}
Warning: make sure you either use a guarded block in the looping code, a method that blocks itself, or a Thread.sleep(..). Thread.sleep is the most primitive of these if you don't understand guarded blocks, but it will work. You could also wait forever and use the interrupt mechanism to cancel the thread which is thrown as InterruptedException in the try-catch block when you use a wait or sleep. For this, use !Thread.currentThread().isInterrupted() as the loop guard condition, then use your Thread object and call thread.interrupt().
To control a Java thread, you should add methods to the object that can be called by other objects which set variables read by your run() method. You don't give much information on exactly what you're doing, but here's a possible pattern:
public class ProgressBarUpdater implements Runnable{
private volatile boolean paused = false;
private volatile boolean finished = false;
/* other fields, constructor etc. */
public void run(){
while(!finished){
updateProgressBar();
while(paused && !finished){
try{
Thread.sleep(1000); //Busy wait - should really use wait/notify, but that's another lesson
}
catch(InterruptedException e){
}
}
}
}
public synchronized void pauseProgressBar(){
paused = true;
}
public synchronized void unPauseProgressBar(){
paused = false;
//call notify() here when you switch to wait/notify.
}
public void stopProgressBar(){
finished = true;
//call notify() here too.
}
}
You will probably want to use more robust synchronisation around the control variables, and, as mentioned in the comments, wait/notify rather than a busy wait.
Use as so:
ProgressBarUpdater pbu = new ProgressBarUpdater();
Thread t = new Thread(pbu);
t.start();
Thread.sleep(10000); //let the progress bar run for ten seconds.
pbu.pauseProgressBar();
Thread.sleep(10000); //pause it for ten seconds.
pbu.unPauseProgressBar();
Thread.sleep(10000); //restart for another ten seconds.
pbu.stopProgressBar(); //stop progress bar.
You have a few options and they depend on how you define the various states of your thread.
A thread is effectively stoped when it exits the run() method.
To "pause" and "resume" a thread's execution you can can use wait() and notify().
To illustrate this, here's a quick example:
class MyThread implements Runnable {
private boolean keepRunning = false;
private boolean isPaused = false;
public void run() {
keepRunning = true;
try {
while (keepRunning) {
// do stuff here
if (isPaused) {
synchronized (this) {
// wait for resume() to be called
wait();
isPaused = false;
}
}
}
} catch (Exception ex) {
// do stuff
}
}
// note that as-is this won't do anything to a paused thread until
// it is resumed.
public void stop() {
keepRunning = false;
}
public void pause() {
isPaused = true;
}
public synchronized void resume() {
// notify anybody waiting on "this"
notify();
}
}
Have the other thread check a boolean flag (isCancelled, or something like that) periodically. Initially is is false.
From your stop button code, set this value to true.
When your thread next checks the flag and finds it to be true, the thread should kill itself.