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 }