001package jmri.util; 002 003import java.util.Date; 004import java.util.Timer; 005import java.util.TimerTask; 006import javax.annotation.Nonnull; 007 008 009/** 010 * Common utility methods for working with (@link java.util.Timer) 011 * <p> 012 * Each {@link java.util.Timer} uses a thread, which means that they're 013 * not throw-away timers: You either track when you can destroy them 014 * (and that destruction is not obvious), or they stick around consuming 015 * resources. 016 * <p> 017 * This class provides most of the functionality of a Timer. 018 * Some differences: 019 * <ul> 020 * <li>When migrating code that uses Timer.cancel() to end operation, you have to 021 * retain references to the individual TimerTask objects and cancel them instead. 022 * </ul> 023 * <p> 024 * For convenience, this also provides methods to ensure that the task is invoked 025 * on a specific JMRI thread. 026 * <p> 027 * Please note the comment in the {@link Timer} Javadoc about how 028 * {@link java.util.concurrent.ScheduledThreadPoolExecutor} might provide a better 029 * underlying implementation. 030 * 031 * @author Bob Jacobsen Copyright 2018 032 */ 033@javax.annotation.concurrent.Immutable 034final public class TimerUtil { 035 036 // Timer implementation methods 037 038 static public void schedule(@Nonnull TimerTask task, @Nonnull Date time) { 039 commonTimer.schedule(task, time); 040 } 041 042 static public void schedule(@Nonnull TimerTask task, @Nonnull Date firstTime, long period) { 043 commonTimer.schedule(task, firstTime, period); 044 } 045 046 static public void schedule(@Nonnull TimerTask task, long delay) { 047 commonTimer.schedule(task, delay); 048 } 049 050 static public void schedule(@Nonnull TimerTask task, long delay, long period) { 051 commonTimer.schedule(task, delay, period); 052 } 053 054 static public void scheduleAtFixedRate(@Nonnull TimerTask task, @Nonnull Date firstTime, long period) { 055 commonTimer.schedule(task, firstTime, period); 056 } 057 058 static public void scheduleAtFixedRate(@Nonnull TimerTask task, long delay, long period) { 059 commonTimer.schedule(task, delay, period); 060 } 061 062 063 // GUI-thread implementation methods 064 065 // arrange to run on GUI thread 066 static private TimerTask gtask(TimerTask task) { 067 return new TimerTask(){ 068 @Override 069 public void run() { 070 ThreadingUtil.runOnGUIEventually(() -> {task.run();}); 071 } 072 }; 073 } 074 075 static public void scheduleOnGUIThread(@Nonnull TimerTask task, @Nonnull Date time) { 076 commonTimer.schedule(gtask(task), time); 077 } 078 079 static public void scheduleOnGUIThread(@Nonnull TimerTask task, @Nonnull Date firstTime, long period) { 080 commonTimer.schedule(gtask(task), firstTime, period); 081 } 082 083 static public void scheduleOnGUIThread(@Nonnull TimerTask task, long delay) { 084 commonTimer.schedule(gtask(task), delay); 085 } 086 087 static public void scheduleOnGUIThread(@Nonnull TimerTask task, long delay, long period) { 088 commonTimer.schedule(gtask(task), delay, period); 089 } 090 091 static public void scheduleAtFixedRateOnGUIThread(@Nonnull TimerTask task, @Nonnull Date firstTime, long period) { 092 commonTimer.schedule(gtask(task), firstTime, period); 093 } 094 095 static public void scheduleAtFixedRateOnGUIThread(@Nonnull TimerTask task, long delay, long period) { 096 commonTimer.schedule(gtask(task), delay, period); 097 } 098 099 100 // arrange to run on layout thread 101 static private TimerTask ltask(TimerTask task) { 102 return new TimerTask(){ 103 @Override 104 public void run() { 105 ThreadingUtil.runOnLayoutEventually(() -> {task.run();}); 106 } 107 }; 108 } 109 110 static public void scheduleOnLayoutThread(@Nonnull TimerTask task, @Nonnull Date time) { 111 commonTimer.schedule(ltask(task), time); 112 } 113 114 static public void scheduleOnLayoutThread(@Nonnull TimerTask task, @Nonnull Date firstTime, long period) { 115 commonTimer.schedule(ltask(task), firstTime, period); 116 } 117 118 static public void scheduleOnLayoutThread(@Nonnull TimerTask task, long delay) { 119 commonTimer.schedule(ltask(task), delay); 120 } 121 122 static public void scheduleOnLayoutThread(@Nonnull TimerTask task, long delay, long period) { 123 commonTimer.schedule(ltask(task), delay, period); 124 } 125 126 static public void scheduleAtFixedRateOnLayoutThread(@Nonnull TimerTask task, @Nonnull Date firstTime, long period) { 127 commonTimer.schedule(ltask(task), firstTime, period); 128 } 129 130 static public void scheduleAtFixedRateOnLayoutThread(@Nonnull TimerTask task, long delay, long period) { 131 commonTimer.schedule(ltask(task), delay, period); 132 } 133 134 135 final static Timer commonTimer = new Timer("JMRI Common Timer", true); 136 137 // private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TimerUtil.class); 138}