Skip to content

Instantly share code, notes, and snippets.

@vegaasen
Last active December 22, 2015 21:39
Show Gist options
  • Save vegaasen/6535079 to your computer and use it in GitHub Desktop.
Save vegaasen/6535079 to your computer and use it in GitHub Desktop.
A simple DaemonThread class
public abstract class DaemonThread implements Runnable {
public static final TimedEvent DEFAULT = new TimedEvent();
private static final String DAEMON_THREAD_ID = "DaemonThread@selfdef";
private Thread thread;
private volatile boolean active;
private boolean daemon = true;
private TimedEvent event;
public DaemonThread() {
setEvent(DEFAULT);
}
public final synchronized void start() {
before();
Thread t = initializeOrGetThread();
if (t != null) {
if (isActive()) {
return;
} else {
try {
thread.setDaemon(daemon);
thread.setName(DAEMON_THREAD_ID);
thread.start();
} finally {
active = true;
}
}
}
after();
}
public final synchronized boolean stop() {
if (isRunning()) {
try {
beforeStop();
interrupt();
afterStop();
reset();
} finally {
active = false;
}
return true;
}
return false;
}
public final synchronized void forceStop() {
try{
interrupt();
reset();
}finally {
active = false;
}
}
protected synchronized Thread initializeOrGetThread() {
if (thread == null) {
thread = new Thread(this);
}
return thread;
}
/**
* Must implement. In the run-method, Use the checkIfUpdateIsRequired() in an if to enable full verification regarding
* the TimedEvent set.
*/
@Override
public abstract void run();
protected synchronized void before() {
}
protected synchronized void after() {
}
protected synchronized void beforeStop() {
}
protected synchronized void afterStop() {
}
private synchronized void interrupt() {
if (isRunning()) {
initializeOrGetThread().interrupt();
}
}
private synchronized boolean isRunning() {
return (thread != null);
}
private synchronized void reset() {
if (thread == null) {
return;
}
thread = null;
}
protected synchronized boolean checkIfUpdateIsRequired() {
return checkIfUpdateIsRequired(System.currentTimeMillis());
}
protected synchronized boolean checkIfUpdateIsRequired(long t) {
if (event.getLastRun() == 0L || (t - event.getLastRun()) > event.getAccumulatedWaitTime()) {
event.setLastRun();
return true;
} else {
return false;
}
}
public synchronized boolean isActive() {
return active;
}
public boolean isDaemon() {
return daemon;
}
/**
* Doesn't make much sense, really..
*
* @param daemon _
*/
public void setDaemon(boolean daemon) {
this.daemon = daemon;
}
public TimedEvent getEvent() {
return event;
}
public synchronized void setEvent(TimedEvent event) {
this.event = event;
}
}
public final class SimpleUsage extends DaemonThread {
@Autowired
private SomeService someService;
@Override
public void run() {
final long sleepTime = getEvent().getAccumulatedWaitTime() - DEFAULT_SLEEP_TIME;
for (; ; ) {
try {
if (checkIfUpdateIsRequired()) {
someService.doStuff();
} else {
try {
Thread.sleep(sleepTime);
} catch (final InterruptedException e) {
//wtf
}
}
} catch (final Exception e) {
break;
}
}
}
}
public class TimedEvent {
private int hours = 0;
private long minutes = 0L;
private long seconds = 0L;
private long milliseconds = 0L;
private long lastRun = 0L;
public int getHours() {
return hours;
}
public void setHours(int hours) {
this.hours = hours;
}
public long getMinutes() {
return minutes;
}
public void setMinutes(long minutes) {
this.minutes = minutes;
}
public long getSeconds() {
return seconds;
}
public void setSeconds(long seconds) {
this.seconds = seconds;
}
public long getMilliseconds() {
return milliseconds;
}
public void setMilliseconds(long milliseconds) {
this.milliseconds = milliseconds;
}
public long getLastRun() {
return lastRun;
}
public void setLastRun() {
this.lastRun = System.currentTimeMillis();
}
public long getAccumulatedWaitTime() {
return
TimeUnit.HOURS.toMillis(hours) +
TimeUnit.MINUTES.toMillis(minutes) +
TimeUnit.SECONDS.toMillis(seconds) +
milliseconds;
}
@Override
public String toString() {
return "TimedEvent{" +
"hours=" + hours +
", minutes=" + minutes +
", seconds=" + seconds +
", milliseconds=" + milliseconds +
'}';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment