1 | package de.uka.ipd.sdq.probespec.framework.concurrency; |
2 | |
3 | import java.util.ArrayList; |
4 | |
5 | /** |
6 | * Maintains a list of threads that has been spawned by the ProbeSpecification. |
7 | * This allows for stopping all running threads at once by using |
8 | * {@link #stopThreads()}. |
9 | * <p> |
10 | * The ThreadManager gets aware of new threads only when threads are spawned |
11 | * using {@link #startThread(StoppableRunnable, String)}, which is the |
12 | * recommended approach. |
13 | * |
14 | * @author Philipp Merkle |
15 | * |
16 | */ |
17 | public class ThreadManager { |
18 | |
19 | private ArrayList<RunnableThreadPair> runnableThreadList; |
20 | |
21 | public ThreadManager() { |
22 | runnableThreadList = new ArrayList<RunnableThreadPair>(); |
23 | } |
24 | |
25 | /** |
26 | * Creates a thread using the specified runnable and starts execution. |
27 | * All threads started that way can be stopped at once by using |
28 | * {@link #stopThreads()}. |
29 | * |
30 | * @param runnable |
31 | * @param threadName |
32 | */ |
33 | public void startThread(StoppableRunnable runnable, String threadName) { |
34 | Thread thread = new Thread(runnable); |
35 | runnableThreadList.add(new RunnableThreadPair(runnable, thread)); |
36 | thread.setName(threadName); |
37 | thread.start(); |
38 | } |
39 | |
40 | /** |
41 | * Stops all threads that has been started using |
42 | * {@link #startThread(StoppableRunnable, String)} and waits for their |
43 | * termination. |
44 | */ |
45 | public void stopThreads() { |
46 | for (RunnableThreadPair p : runnableThreadList) { |
47 | p.getRunnable().stop(); |
48 | } |
49 | |
50 | for (RunnableThreadPair p : runnableThreadList) { |
51 | // Wait for the thread to finish |
52 | try { |
53 | // TODO: maybe use join with parameter in order to avoid waiting |
54 | // forever |
55 | p.getThread().join(); |
56 | } catch (InterruptedException e) { |
57 | // TODO Auto-generated catch block |
58 | e.printStackTrace(); |
59 | } |
60 | } |
61 | |
62 | // all threads have stopped, we don't need the thread list anymore |
63 | runnableThreadList.clear(); |
64 | } |
65 | |
66 | /** |
67 | * (StoppableRunnable, Thread)-Pair |
68 | */ |
69 | private class RunnableThreadPair { |
70 | |
71 | private StoppableRunnable runnable; |
72 | |
73 | private Thread thread; |
74 | |
75 | public RunnableThreadPair(StoppableRunnable runnable, Thread thread) { |
76 | this.runnable = runnable; |
77 | this.thread = thread; |
78 | } |
79 | |
80 | public StoppableRunnable getRunnable() { |
81 | return runnable; |
82 | } |
83 | |
84 | public Thread getThread() { |
85 | return thread; |
86 | } |
87 | |
88 | } |
89 | |
90 | } |