I'm writing a search-as-you-type mechanism (android) that makes an sqlite query in a background thread and posts the results back to the UI thread. Ideally, the thread should wait/sleep, wake up to execute any received Runnable object and go back to sleep. what's the best way to achieve this and why?
Basically I want to understand what are the key differences between these 3 options and which one is best for this exact scenario
sleep/interrupt
public class AsyncExecutorSleepInterrupt { private static Thread thread; private static Runnable runnable; static { thread = new Thread(() -> { while (true) { try { Thread.sleep(10000); } catch (InterruptedException e) { if (runnable != null) { runnable.run(); runnable = null; } } } }); thread.start(); } public static void execute(Runnable runnable) { AsyncExecutorSleepInterrupt.runnable = runnable; thread.interrupt(); }}
wait/notify
public class AsyncExecutorWaitNotify { private static Thread thread; private static Runnable runnable; private static final Object monitor = new Object(); static { thread = new Thread(() -> { while (true) { synchronized (monitor) { try { monitor.wait(); } catch (InterruptedException e) { e.printStackTrace(); continue; } if (runnable != null) { runnable.run(); runnable = null; } } } }); thread.start(); } public static void execute(Runnable runnable) { AsyncExecutorWaitNotify.runnable = runnable; synchronized (monitor) { monitor.notify(); } }}
ReentrantLock
public class AsyncExecutorLockCondition { private static final ReentrantLock lock = new ReentrantLock(); private static final Condition cond = lock.newCondition(); private static Thread thread; private static Runnable runnable; static { thread = new Thread(() -> { while(true){ try { lock.lock(); cond.await(); runnable.run(); lock.unlock(); } catch (InterruptedException e) { e.printStackTrace(); } } }); thread.start(); } public static void execute(Runnable runnable) { AsyncExecutorLockCondition.runnable = runnable; lock.lock(); cond.signal(); lock.unlock(); }}