RuntimeService.java 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /**
  2. Copyright (c) 2012-2015 committers of YAKINDU and others.
  3. All rights reserved. This program and the accompanying materials
  4. are made available under the terms of the Eclipse Public License v1.0
  5. which accompanies this distribution, and is available at
  6. http://www.eclipse.org/legal/epl-v10.html
  7. Contributors:
  8. committers of YAKINDU - initial API and implementation
  9. �*/
  10. package traffic.light;
  11. import java.util.HashMap;
  12. import java.util.LinkedList;
  13. import java.util.List;
  14. import java.util.Map;
  15. import java.util.Timer;
  16. import java.util.TimerTask;
  17. import java.util.concurrent.locks.ReentrantReadWriteLock;
  18. /**
  19. * Runtime service for state machines to execute a run to completion step
  20. * periodically.
  21. *
  22. */
  23. public class RuntimeService {
  24. private static RuntimeService runtimeService;
  25. private Timer timer = null;
  26. private Map<Long, StatemachineTimerTask> timerTasks = new HashMap<Long, StatemachineTimerTask>();
  27. private class StatemachineTimerTask extends TimerTask {
  28. private List<IStatemachine> statemachineList = new LinkedList<IStatemachine>();
  29. private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
  30. private boolean isPaused = false;
  31. @Override
  32. public void run() {
  33. lock.readLock().lock();
  34. if (!isPaused) {
  35. for (IStatemachine statemachine : statemachineList) {
  36. statemachine.runCycle();
  37. }
  38. }
  39. lock.readLock().unlock();
  40. }
  41. /**
  42. * Adds the given state machine to the TimerTask.
  43. *
  44. * @param statemachine
  45. * @return {@code true} if state machine is added properly.
  46. */
  47. public boolean addStatemachine(IStatemachine statemachine) {
  48. lock.writeLock().lock();
  49. boolean ret = statemachineList.add(statemachine);
  50. lock.writeLock().unlock();
  51. return ret;
  52. }
  53. /**
  54. * Removes the given state machine from the TimerTask.
  55. *
  56. * @param statemachine
  57. * @return {@code true} if state machine is removed properly.
  58. */
  59. public boolean removeStatemachine(IStatemachine statemachine) {
  60. lock.writeLock().lock();
  61. boolean ret = statemachineList.remove(statemachine);
  62. lock.writeLock().unlock();
  63. return ret;
  64. }
  65. public void pause() {
  66. isPaused = true;
  67. }
  68. public void resume() {
  69. isPaused = false;
  70. }
  71. }
  72. private RuntimeService() {
  73. // Not intended to be instantiated.
  74. }
  75. /**
  76. * Returns the {@code RuntimeService} instance as singleton.
  77. *
  78. * @return The singleton {@code RuntimeService} instance
  79. */
  80. public static RuntimeService getInstance() {
  81. if (runtimeService == null) {
  82. runtimeService = new RuntimeService();
  83. }
  84. return runtimeService;
  85. }
  86. /**
  87. * Registers an {@link IStatemachine} for scheduled fixed rate execution
  88. *
  89. * @param statemachine
  90. * - The state machine to execute
  91. * @param cyclePeriod
  92. * - the fixed rate cycle period for scheduling
  93. * @return {@code true} if state machine is added properly.
  94. */
  95. public boolean registerStatemachine(IStatemachine statemachine,
  96. long cyclePeriod) {
  97. if (timerTasks.containsKey(cyclePeriod)) {
  98. // TimerTask for cycle time already existing -> add state machine
  99. return timerTasks.get(cyclePeriod).addStatemachine(statemachine);
  100. } else {
  101. // Create new TimerTask for cycle period and add state machine
  102. StatemachineTimerTask timerTask = new StatemachineTimerTask();
  103. timerTasks.put(cyclePeriod, timerTask);
  104. boolean ret = timerTask.addStatemachine(statemachine);
  105. // Create a new Timer instance if runtime service was cancelled
  106. // before
  107. if (timer == null) {
  108. timer = new Timer();
  109. }
  110. timer.scheduleAtFixedRate(timerTask, 0, cyclePeriod);
  111. return ret;
  112. }
  113. }
  114. /**
  115. * Removes the given state machine from runtime service.
  116. *
  117. * @param statemachine
  118. * - the state machine which should be removed
  119. * @param cyclePeriod
  120. * - the scheduling cycle period of the state machine
  121. * @return {@code true} if state machine is removed properly.
  122. */
  123. public boolean unregisterStatemachine(IStatemachine statemachine,
  124. long cyclePeriod) {
  125. if (timerTasks.containsKey(cyclePeriod)) {
  126. boolean ret = timerTasks.get(cyclePeriod).removeStatemachine(
  127. statemachine);
  128. return ret;
  129. }
  130. return false;
  131. }
  132. /**
  133. * Cancels the execution of state machines for the given cycle period. This
  134. * stops the execution of state machines which are registered for the given
  135. * cycle period and cancels the executing {@link TimerTask}.
  136. *
  137. * @return {@code true} if poperly cancelled
  138. */
  139. public boolean cancelAll(long cyclePeriod) {
  140. if (timer != null && timerTasks.containsKey(cyclePeriod)) {
  141. TimerTask task = timerTasks.get(cyclePeriod);
  142. task.cancel();
  143. timer.purge();
  144. timerTasks.remove(cyclePeriod);
  145. return true;
  146. }
  147. return false;
  148. }
  149. /**
  150. * Pauses the execution of all state machines which are registered for the
  151. * given cyclePeriod.
  152. *
  153. * @param cyclePeriod
  154. * @return {@code true} if properly paused
  155. *
  156. */
  157. public boolean pauseAll(long cyclePeriod) {
  158. if (timerTasks.containsKey(cyclePeriod)) {
  159. timerTasks.get(cyclePeriod).pause();
  160. return true;
  161. }
  162. return false;
  163. }
  164. /**
  165. * Resumes the execution of all state machines which are registered for the
  166. * given cyclePeriod.
  167. *
  168. * @param cyclePeriod
  169. * @return {@code true} if properly resumed
  170. *
  171. */
  172. public boolean resumeAll(long cyclePeriod) {
  173. if (timerTasks.containsKey(cyclePeriod)) {
  174. timerTasks.get(cyclePeriod).resume();
  175. return true;
  176. }
  177. return false;
  178. }
  179. /**
  180. * Cancels the execution of all registered state machines. This cancels the
  181. * executing {@link Timer} freeing all allocated resources and terminates
  182. * all existing execution threads.
  183. */
  184. public void cancelTimer() {
  185. if (timer != null) {
  186. timer.cancel();
  187. timer.purge();
  188. timerTasks.clear();
  189. timer = null;
  190. }
  191. }
  192. }