View Javadoc
1   package nl.tudelft.simulation.language.concurrent;
2   
3   import java.util.concurrent.atomic.AtomicBoolean;
4   
5   import org.djutils.logger.CategoryLogger;
6   
7   /**
8    * The WorkerThread is a working thread. The thread sleeps while not interrupted. If interrupted the job.run operation is
9    * invoked.
10   * <p>
11   * Copyright (c) 2002-2024 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
12   * for project information <a href="https://simulation.tudelft.nl/" target="_blank"> https://simulation.tudelft.nl</a>. The DSOL
13   * project is distributed under a three-clause BSD-style license, which can be found at
14   * <a href="https://https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank">
15   * https://https://simulation.tudelft.nl/dsol/docs/latest/license.html</a>.
16   * </p>
17   * @author <a href="mailto:phmjacobs@hotmail.com">Peter H.M. Jacobs</a>
18   * @author <a href="http://tudelft.nl/averbraeck">Alexander Verbraeck</a>
19   */
20  
21  public class WorkerThread extends Thread
22  {
23      /** the job to execute. */
24      private Runnable job = null;
25  
26      /** finalized. */
27      private boolean finalized = false;
28  
29      /** running. */
30      private AtomicBoolean running = new AtomicBoolean(false);
31  
32      /**
33       * constructs a new SimulatorRunThread.
34       * @param name String; the name of the thread
35       * @param job Runnable; the job to run
36       */
37      public WorkerThread(final String name, final Runnable job)
38      {
39          super(name);
40          this.job = job;
41          this.setDaemon(false);
42          this.setPriority(Thread.NORM_PRIORITY);
43          this.start();
44      }
45  
46      /**
47       * Clean up the worker thread. synchronized method, otherwise it does not own the Monitor on the wait.
48       */
49      public synchronized void cleanUp()
50      {
51          this.running.set(false);
52          this.finalized = true;
53          if (!this.isInterrupted())
54          {
55              this.notify(); // in case it is in the 'wait' state
56          }
57          this.job = null;
58      }
59  
60      /**
61       * @return whether the run method of the job is running or not
62       */
63      public synchronized boolean isRunning()
64      {
65          return this.running.get();
66      }
67  
68      /** {@inheritDoc} */
69      @Override
70      public synchronized void run()
71      {
72          while (!this.finalized) // always until finalized
73          {
74              try
75              {
76                  this.wait(); // as long as possible
77              }
78              catch (InterruptedException interruptedException)
79              {
80                  if (!this.finalized)
81                  {
82                      this.interrupt(); // set the status to interrupted
83                      try
84                      {
85                          this.running.set(true);
86                          this.job.run();
87                          this.running.set(false);
88                      }
89                      catch (Exception exception)
90                      {
91                          CategoryLogger.always().error(exception);
92                      }
93                      Thread.interrupted();
94                  }
95              }
96          }
97      }
98  }