1a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson/* 2a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Written by Doug Lea with assistance from members of JCP JSR-166 3a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Expert Group and released to the public domain, as explained at 4a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/ 5a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 6a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 7a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilsonpackage java.util.concurrent; 8a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 9a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson/** 10a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * A thread managed by a {@link ForkJoinPool}, which executes 11a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * {@link ForkJoinTask}s. 12a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * This class is subclassable solely for the sake of adding 13a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * functionality -- there are no overridable methods dealing with 14a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * scheduling or execution. However, you can override initialization 15a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * and termination methods surrounding the main task processing loop. 16a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * If you do create such a subclass, you will also need to supply a 1775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * custom {@link ForkJoinPool.ForkJoinWorkerThreadFactory} to 1875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * {@linkplain ForkJoinPool#ForkJoinPool use it} in a {@code ForkJoinPool}. 19a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * 20a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * @since 1.7 21a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * @author Doug Lea 22a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 23a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilsonpublic class ForkJoinWorkerThread extends Thread { 24a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /* 25a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * ForkJoinWorkerThreads are managed by ForkJoinPools and perform 2691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * ForkJoinTasks. For explanation, see the internal documentation 2791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * of class ForkJoinPool. 28a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * 2991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * This class just maintains links to its pool and WorkQueue. The 3091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * pool field is set immediately upon construction, but the 3191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * workQueue field is not set until a call to registerWorker 3291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * completes. This leads to a visibility race, that is tolerated 3391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * by requiring that the workQueue field is only accessed by the 3491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * owning thread. 35a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 36a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 3791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle final ForkJoinPool pool; // the pool this thread works in 3891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle final ForkJoinPool.WorkQueue workQueue; // work-stealing mechanics 39a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 40a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 41a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Creates a ForkJoinWorkerThread operating in the given pool. 42a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * 43a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * @param pool the pool this thread works in 44a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * @throws NullPointerException if pool is null 45a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 46a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson protected ForkJoinWorkerThread(ForkJoinPool pool) { 4791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle // Use a placeholder until a useful name can be set in registerWorker 4891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle super("aForkJoinWorkerThread"); 49a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson this.pool = pool; 5091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle this.workQueue = pool.registerWorker(this); 51a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 52a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 53a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 54a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Returns the pool hosting this thread. 55a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * 56a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * @return the pool 57a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 58a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson public ForkJoinPool getPool() { 59a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson return pool; 60a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 61a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 62a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 6375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * Returns the unique index number of this thread in its pool. 6475a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * The returned value ranges from zero to the maximum number of 6575a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * threads (minus one) that may exist in the pool, and does not 6675a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * change during the lifetime of the thread. This method may be 6775a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * useful for applications that track status or collect results 6875a06e56a4cc4599946e21422513e4bafa759509Calin Juravle * per-worker-thread rather than per-task. 69a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * 70a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * @return the index number 71a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 72a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson public int getPoolIndex() { 7375a06e56a4cc4599946e21422513e4bafa759509Calin Juravle return workQueue.poolIndex >>> 1; // ignore odd/even tag bit 74a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 75a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 76a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 77a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Initializes internal state after construction but before 78a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * processing any tasks. If you override this method, you must 79a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * invoke {@code super.onStart()} at the beginning of the method. 80a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Initialization requires care: Most fields must have legal 81a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * default values, to ensure that attempted accesses from other 82a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * threads work correctly even before this thread starts 83a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * processing tasks. 84a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 85a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson protected void onStart() { 86a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 87a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 88a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 89a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Performs cleanup associated with termination of this worker 90a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * thread. If you override this method, you must invoke 91a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * {@code super.onTermination} at the end of the overridden method. 92a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * 93a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * @param exception the exception causing this thread to abort due 94a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * to an unrecoverable error, or {@code null} if completed normally 95a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 96a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson protected void onTermination(Throwable exception) { 97a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 98a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 99a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 100a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * This method is required to be public, but should never be 101a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * called explicitly. It performs the main run loop to execute 102a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * {@link ForkJoinTask}s. 103a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 104a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson public void run() { 105a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson Throwable exception = null; 106a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson try { 107a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson onStart(); 10891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle pool.runWorker(workQueue); 109a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } catch (Throwable ex) { 110a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson exception = ex; 111a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } finally { 11291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle try { 11391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle onTermination(exception); 11491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle } catch (Throwable ex) { 11591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle if (exception == null) 11691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle exception = ex; 11791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle } finally { 11891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle pool.deregisterWorker(this, exception); 119a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 120a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 121a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 122a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson} 123