練習用メモ。 AlarmListener: #code|java|> package timer; public interface AlarmListener { public void onAlarm(); } ||< PeriodicAlarm: #code|java|> package timer; import java.util.HashSet; import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; /** http://www.02.246.ne.jp/~torutk/javahow2/timer.html#doc1_id120 http://d.hatena.ne.jp/AWAWA/20080423/1208955538 http://www.ibm.com/developerworks/jp/java/library/j-5things5.html */ public class PeriodicAlarm implements Runnable { ScheduledFuture future; ScheduledExecutorService executorService; final Set listeners = new HashSet<>(); final long initialDelay; final long period; final TimeUnit timeUnit; public PeriodicAlarm(long initialDelay, long period, TimeUnit timeUnit) { this.executorService = Executors.newScheduledThreadPool(1); this.initialDelay = initialDelay; this.period = period; this.timeUnit = timeUnit; } public void start() { this.future = this.executorService.scheduleAtFixedRate(this, this.initialDelay, this.period, this.timeUnit); } public void stop() { this.future.cancel(true); } public void shutdown() { this.stop(); this.executorService.shutdown(); } public void addAlarmListener(AlarmListener l) { synchronized (listeners) { listeners.add(l); } } public void removeAlarmListener(AlarmListener l) { synchronized (listeners) { listeners.remove(l); } } @Override public void run() { synchronized (listeners) { for (AlarmListener l : this.listeners) { l.onAlarm(); } } } } ||< PeriodicAlarmTest: #code|java|> import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.concurrent.TimeUnit; import static org.testng.Assert.*; import org.testng.annotations.Test; import timer.AlarmListener; import timer.PeriodicAlarm; public class PeriodicAlarmTest { public PeriodicAlarmTest() { } class Countup implements AlarmListener { String name; int count = 0; final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-DD HH:mm:ss.SSS"); public Countup(String name) { this.name = name; } @Override public void onAlarm() { Calendar c = Calendar.getInstance(); String snow; synchronized (this.sdf) { snow = sdf.format(c.getTime()); } count++; System.out.println("[" + this.name + "]:now=" + snow + ", count=" + count); } } @Test public void hello() throws InterruptedException { PeriodicAlarm a = new PeriodicAlarm(0, 1, TimeUnit.SECONDS); a.start(); Countup c1 = new Countup("c1"); a.addAlarmListener(c1); Thread.sleep(2 * 1000); Countup c2 = new Countup("c2"); a.addAlarmListener(c2); Thread.sleep(2 * 1000); Countup c3 = new Countup("c3"); a.addAlarmListener(c3); Thread.sleep(2 * 1000); a.shutdown(); assertEquals(c1.count, 6); assertEquals(c2.count, 4); assertEquals(c3.count, 2); } } ||<