ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166y/ForkJoinWorkerThread.java
Revision: 1.72
Committed: Mon Nov 19 18:12:42 2012 UTC (11 years, 6 months ago) by dl
Branch: MAIN
Changes since 1.71: +24 -15 lines
Log Message:
better memory positioning

File Contents

# User Rev Content
1 dl 1.1 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain, as explained at
4 jsr166 1.64 * http://creativecommons.org/publicdomain/zero/1.0/
5 dl 1.1 */
6    
7     package jsr166y;
8 jsr166 1.18
9 dl 1.72 import java.util.concurrent.atomic.AtomicInteger;
10    
11 dl 1.1 /**
12 dl 1.59 * A thread managed by a {@link ForkJoinPool}, which executes
13     * {@link ForkJoinTask}s.
14     * This class is subclassable solely for the sake of adding
15     * functionality -- there are no overridable methods dealing with
16     * scheduling or execution. However, you can override initialization
17     * and termination methods surrounding the main task processing loop.
18     * If you do create such a subclass, you will also need to supply a
19     * custom {@link ForkJoinPool.ForkJoinWorkerThreadFactory} to use it
20     * in a {@code ForkJoinPool}.
21 jsr166 1.6 *
22 jsr166 1.13 * @since 1.7
23     * @author Doug Lea
24 dl 1.1 */
25     public class ForkJoinWorkerThread extends Thread {
26     /*
27 dl 1.31 * ForkJoinWorkerThreads are managed by ForkJoinPools and perform
28 dl 1.68 * ForkJoinTasks. For explanation, see the internal documentation
29     * of class ForkJoinPool.
30 dl 1.72 *
31     * This class just maintains links to its pool and WorkQueue. The
32     * pool field is set upon construction, but the workQueue field is
33     * not set until the thread has started (unless forced early by a
34     * subclass constructor call to poolIndex()). This provides
35     * better memory placement (because this thread allocates queue
36     * and bookkeeping fields) but because the field is non-final, we
37     * require that it never be accessed except by the owning thread.
38 dl 1.40 */
39    
40 dl 1.68 final ForkJoinPool pool; // the pool this thread works in
41 dl 1.72 ForkJoinPool.WorkQueue workQueue; // Work-stealing mechanics
42 dl 1.36
43     /**
44 dl 1.72 * Sequence number for creating worker Names
45 dl 1.71 */
46 dl 1.72 private static final AtomicInteger threadNumber = new AtomicInteger();
47 dl 1.71
48     /**
49 dl 1.1 * Creates a ForkJoinWorkerThread operating in the given pool.
50 jsr166 1.11 *
51 dl 1.1 * @param pool the pool this thread works in
52     * @throws NullPointerException if pool is null
53     */
54     protected ForkJoinWorkerThread(ForkJoinPool pool) {
55 dl 1.72 super(pool.workerNamePrefix.concat(Integer.toString(threadNumber.incrementAndGet())));
56     setDaemon(true);
57     this.pool = pool;
58 dl 1.63 Thread.UncaughtExceptionHandler ueh = pool.ueh;
59 dl 1.31 if (ueh != null)
60     setUncaughtExceptionHandler(ueh);
61     }
62    
63 dl 1.2 /**
64 jsr166 1.11 * Returns the pool hosting this thread.
65     *
66 dl 1.2 * @return the pool
67     */
68 dl 1.4 public ForkJoinPool getPool() {
69     return pool;
70 dl 1.2 }
71    
72     /**
73 dl 1.4 * Returns the index number of this thread in its pool. The
74     * returned value ranges from zero to the maximum number of
75     * threads (minus one) that have ever been created in the pool.
76     * This method may be useful for applications that track status or
77 dl 1.5 * collect results per-worker rather than per-task.
78 jsr166 1.11 *
79     * @return the index number
80 dl 1.2 */
81 dl 1.4 public int getPoolIndex() {
82 dl 1.72 // force early registration if called before started
83     ForkJoinPool.WorkQueue q;
84     if ((q = workQueue) == null) {
85     pool.registerWorker(this);
86     q = workQueue;
87     }
88     return q.poolIndex;
89 dl 1.2 }
90    
91 dl 1.7 /**
92 dl 1.31 * Initializes internal state after construction but before
93     * processing any tasks. If you override this method, you must
94 jsr166 1.58 * invoke {@code super.onStart()} at the beginning of the method.
95 dl 1.31 * Initialization requires care: Most fields must have legal
96     * default values, to ensure that attempted accesses from other
97     * threads work correctly even before this thread starts
98     * processing tasks.
99 dl 1.7 */
100 dl 1.31 protected void onStart() {
101     }
102 dl 1.5
103     /**
104 dl 1.31 * Performs cleanup associated with termination of this worker
105     * thread. If you override this method, you must invoke
106     * {@code super.onTermination} at the end of the overridden method.
107 jsr166 1.21 *
108 dl 1.31 * @param exception the exception causing this thread to abort due
109     * to an unrecoverable error, or {@code null} if completed normally
110 dl 1.5 */
111 dl 1.31 protected void onTermination(Throwable exception) {
112 dl 1.5 }
113    
114     /**
115     * This method is required to be public, but should never be
116     * called explicitly. It performs the main run loop to execute
117 dl 1.59 * {@link ForkJoinTask}s.
118 dl 1.1 */
119 dl 1.5 public void run() {
120     Throwable exception = null;
121     try {
122 dl 1.72 pool.registerWorker(this);
123 dl 1.5 onStart();
124 dl 1.69 pool.runWorker(workQueue);
125 dl 1.5 } catch (Throwable ex) {
126     exception = ex;
127     } finally {
128 jsr166 1.6 try {
129 dl 1.68 onTermination(exception);
130     } catch (Throwable ex) {
131     if (exception == null)
132     exception = ex;
133     } finally {
134     pool.deregisterWorker(this, exception);
135 jsr166 1.6 }
136     }
137     }
138 dl 1.1 }