Cheok Yan Cheng Cheok Yan Cheng -4 years ago 94
Java Question

Interrrupt-able ScheduledExecutorService in Android

Currently, I am designing a stock market app with the following requirement


  • 1) Scan stock price repeatedly, with a fixed sleep time.

  • 2) Able to interrupt the sleep any-time. This is because when user adds a new stock, we need to wake up from sleep, and scan immediately.



Previously, I'm using bare bone
Thread
, to full-fill the above 2 requirements.

private class StockMonitor extends Thread {
@Override
public void run() {
final Thread thisThread = Thread.currentThread();

while (thisThread == thread) {

// Fetch stock prices...

try {
Thread.sleep(MIN_DELAY);
} catch (java.lang.InterruptedException exp) {
if (false == refreshed()) {
/* Exit the primary fail safe loop. */
thread = null;
break;
}
}
}
}

public synchronized void refresh() {
isRefresh = true;
interrupt();
}

private synchronized boolean refreshed() {
if (isRefresh) {
isRefresh = false;
// Interrupted status of the thread is cleared.
interrupted();
return true;
}
return false;
}
}


When I want to perform requirement (2), I will call
refresh
. Thread will be waked up, and perform job immediately.

However, I feel it is difficult to maintain such bare bone Thread code, and can make mistake easily.

I prefer to use
ScheduledExecutorService
. However, it lack of ability for me to wake up the Thread from sleeping state, and perform job immediately.

I was wondering, is there any classes in Android, which enables me to perform periodically task as in
ScheduledExecutorService
? Yet has the ability to wake up the Thread from sleeping state, and perform job immediately.

Answer Source

Here is my solution with ScheduledThreadPoolExecutor. To cancel existing tasks, issue future.cancel() on Future object returned from scheduleAtFixedRate(). Then call scheduleAtFixedRate() again with initial delay set to 0.

class HiTask implements Runnable {
    @Override
    public void run() {
        System.out.println("Say Hi!");
    } 
}

// periodically execute task in every 100 ms, without initial delay time

ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);

long initialDelay = 0;
long period = 100;

ScheduledFuture<?> future1 = exec.scheduleAtFixedRate(new HiTask(), initialDelay, period, TimeUnit.MILLISECONDS);


// to trigger task execution immediately

boolean success = future.cancel(true);    // mayInterruptIfRunning = true: interrupt thread even task has already started

ScheduledFuture<?> future2 = exec.scheduleAtFixedRate(new HiTask(), initialDelay, period, TimeUnit.MILLISECONDS);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download