18 |
|
* lighter weight than a normal thread. Huge numbers of tasks and |
19 |
|
* subtasks may be hosted by a small number of actual threads in a |
20 |
|
* ForkJoinPool, at the price of some usage limitations. |
21 |
< |
* |
21 |
> |
* |
22 |
|
* <p> A "main" ForkJoinTask begins execution when submitted to a |
23 |
|
* {@link ForkJoinPool}. Once started, it will usually in turn start |
24 |
|
* other subtasks. As indicated by the name of this class, many |
28 |
|
* of other methods that can come into play in advanced usages, as |
29 |
|
* well as extension mechanics that allow support of new forms of |
30 |
|
* fork/join processing. |
31 |
< |
* |
31 |
> |
* |
32 |
|
* <p>A ForkJoinTask is a lightweight form of {@link Future}. The |
33 |
|
* efficiency of ForkJoinTasks stems from a set of restrictions (that |
34 |
|
* are only partially statically enforceable) reflecting their |
82 |
|
* instances of different task subclasses to call each others |
83 |
|
* methods), some of them may only be called from within other |
84 |
|
* ForkJoinTasks. Attempts to invoke them in other contexts result in |
85 |
< |
* exceptions or errors including ClassCastException. |
85 |
> |
* exceptions or errors possibly including ClassCastException. |
86 |
|
* |
87 |
|
* <p>Most base support methods are <code>final</code> because their |
88 |
|
* implementations are intrinsically tied to the underlying |
475 |
|
* than once unless it has completed and been reinitialized. This |
476 |
|
* method may be invoked only from within ForkJoinTask |
477 |
|
* computations. Attempts to invoke in other contexts result in |
478 |
< |
* exceptions or errors including ClassCastException. |
478 |
> |
* exceptions or errors possibly including ClassCastException. |
479 |
|
*/ |
480 |
|
public final void fork() { |
481 |
|
((ForkJoinWorkerThread)(Thread.currentThread())).pushTask(this); |
515 |
|
* both of them or an exception is encountered. This method may be |
516 |
|
* invoked only from within ForkJoinTask computations. Attempts to |
517 |
|
* invoke in other contexts result in exceptions or errors |
518 |
< |
* including ClassCastException. |
518 |
> |
* possibly including ClassCastException. |
519 |
|
* @param t1 one task |
520 |
|
* @param t2 the other task |
521 |
|
* @throws NullPointerException if t1 or t2 are null |
532 |
|
* for all of them. If any task encounters an exception, others |
533 |
|
* may be cancelled. This method may be invoked only from within |
534 |
|
* ForkJoinTask computations. Attempts to invoke in other contexts |
535 |
< |
* result in exceptions or errors including ClassCastException. |
535 |
> |
* result in exceptions or errors possibly including ClassCastException. |
536 |
|
* @param tasks the array of tasks |
537 |
|
* @throws NullPointerException if tasks or any element are null. |
538 |
|
* @throws RuntimeException or Error if any task did so. |
576 |
|
* encounters an exception, others may be cancelled. This method |
577 |
|
* may be invoked only from within ForkJoinTask |
578 |
|
* computations. Attempts to invoke in other contexts resul!t in |
579 |
< |
* exceptions or errors including ClassCastException. |
579 |
> |
* exceptions or errors possibly including ClassCastException. |
580 |
|
* @param tasks the collection of tasks |
581 |
|
* @throws NullPointerException if tasks or any element are null. |
582 |
|
* @throws RuntimeException or Error if any task did so. |
758 |
|
* while helping. (This usually holds for pure divide-and-conquer |
759 |
|
* tasks). This method may be invoked only from within |
760 |
|
* ForkJoinTask computations. Attempts to invoke in other contexts |
761 |
< |
* resul!t in exceptions or errors including ClassCastException. |
761 |
> |
* resul!t in exceptions or errors possibly including ClassCastException. |
762 |
|
* @return the computed result |
763 |
|
*/ |
764 |
|
public final V helpJoin() { |
772 |
|
* Possibly executes other tasks until this task is ready. This |
773 |
|
* method may be invoked only from within ForkJoinTask |
774 |
|
* computations. Attempts to invoke in other contexts resul!t in |
775 |
< |
* exceptions or errors including ClassCastException. |
775 |
> |
* exceptions or errors possibly including ClassCastException. |
776 |
|
*/ |
777 |
|
public final void quietlyHelpJoin() { |
778 |
|
if (status >= 0) { |
855 |
|
* alternative local processing of tasks that could have been, but |
856 |
|
* were not, stolen. This method may be invoked only from within |
857 |
|
* ForkJoinTask computations. Attempts to invoke in other contexts |
858 |
< |
* result in exceptions or errors including ClassCastException. |
858 |
> |
* result in exceptions or errors possibly including ClassCastException. |
859 |
|
* @return true if unforked |
860 |
|
*/ |
861 |
|
public boolean tryUnfork() { |
926 |
|
protected abstract boolean exec(); |
927 |
|
|
928 |
|
/** |
929 |
< |
* Returns, but does not unschedule or execute, the task most |
930 |
< |
* recently forked by the current thread but not yet executed, if |
931 |
< |
* one is available. There is no guarantee that this task will |
932 |
< |
* actually be polled or executed next. |
933 |
< |
* This method is designed primarily to support extensions, |
934 |
< |
* and is unlikely to be useful otherwise. |
929 |
> |
* Returns, but does not unschedule or execute, the task queued by |
930 |
> |
* the current thread but not yet executed, if one is |
931 |
> |
* available. There is no guarantee that this task will actually |
932 |
> |
* be polled or executed next. This method is designed primarily |
933 |
> |
* to support extensions, and is unlikely to be useful otherwise. |
934 |
> |
* This method may be invoked only from within ForkJoinTask |
935 |
> |
* computations. Attempts to invoke in other contexts result in |
936 |
> |
* exceptions or errors possibly including ClassCastException. |
937 |
|
* |
938 |
|
* @return the next task, or null if none are available |
939 |
|
*/ |
942 |
|
} |
943 |
|
|
944 |
|
/** |
945 |
< |
* Unschedules and returns, without executing, the task most |
946 |
< |
* recently forked by the current thread but not yet executed. |
947 |
< |
* This method is designed primarily to support extensions, |
948 |
< |
* and is unlikely to be useful otherwise. |
945 |
> |
* Unschedules and returns, without executing, the next task |
946 |
> |
* queued by the current thread but not yet executed. This method |
947 |
> |
* is designed primarily to support extensions, and is unlikely to |
948 |
> |
* be useful otherwise. This method may be invoked only from |
949 |
> |
* within ForkJoinTask computations. Attempts to invoke in other |
950 |
> |
* contexts result in exceptions or errors possibly including |
951 |
> |
* ClassCastException. |
952 |
|
* |
953 |
|
* @return the next task, or null if none are available |
954 |
|
*/ |
955 |
|
protected static ForkJoinTask<?> pollNextLocalTask() { |
956 |
< |
return ((ForkJoinWorkerThread)(Thread.currentThread())).popTask(); |
956 |
> |
return ((ForkJoinWorkerThread)(Thread.currentThread())).pollLocalTask(); |
957 |
|
} |
958 |
< |
|
958 |
> |
|
959 |
|
/** |
960 |
< |
* Unschedules and returns, without executing, the task most |
961 |
< |
* recently forked by the current thread but not yet executed, if |
962 |
< |
* one is available, or if not available, a task that was forked |
963 |
< |
* by some other thread, if available. Availability may be |
964 |
< |
* transient, so a <code>null</code> result does not necessarily |
965 |
< |
* imply quiecence of the pool this task is operating in. |
966 |
< |
* This method is designed primarily to support extensions, |
967 |
< |
* and is unlikely to be useful otherwise. |
968 |
< |
* |
960 |
> |
* Unschedules and returns, without executing, the next task |
961 |
> |
* queued by the current thread but not yet executed, if one is |
962 |
> |
* available, or if not available, a task that was forked by some |
963 |
> |
* other thread, if available. Availability may be transient, so a |
964 |
> |
* <code>null</code> result does not necessarily imply quiecence |
965 |
> |
* of the pool this task is operating in. This method is designed |
966 |
> |
* primarily to support extensions, and is unlikely to be useful |
967 |
> |
* otherwise. This method may be invoked only from within |
968 |
> |
* ForkJoinTask computations. Attempts to invoke in other contexts |
969 |
> |
* result in exceptions or errors possibly including |
970 |
> |
* ClassCastException. |
971 |
> |
* |
972 |
|
* @return a task, or null if none are available |
973 |
|
*/ |
974 |
|
protected static ForkJoinTask<?> pollTask() { |
975 |
|
return ((ForkJoinWorkerThread)(Thread.currentThread())). |
976 |
< |
pollLocalOrStolenTask(); |
976 |
> |
pollTask(); |
977 |
|
} |
978 |
|
|
979 |
|
// Serialization support |
1008 |
|
} |
1009 |
|
|
1010 |
|
// Temporary Unsafe mechanics for preliminary release |
1011 |
+ |
private static Unsafe getUnsafe() throws Throwable { |
1012 |
+ |
try { |
1013 |
+ |
return Unsafe.getUnsafe(); |
1014 |
+ |
} catch (SecurityException se) { |
1015 |
+ |
try { |
1016 |
+ |
return java.security.AccessController.doPrivileged |
1017 |
+ |
(new java.security.PrivilegedExceptionAction<Unsafe>() { |
1018 |
+ |
public Unsafe run() throws Exception { |
1019 |
+ |
return getUnsafePrivileged(); |
1020 |
+ |
}}); |
1021 |
+ |
} catch (java.security.PrivilegedActionException e) { |
1022 |
+ |
throw e.getCause(); |
1023 |
+ |
} |
1024 |
+ |
} |
1025 |
+ |
} |
1026 |
+ |
|
1027 |
+ |
private static Unsafe getUnsafePrivileged() |
1028 |
+ |
throws NoSuchFieldException, IllegalAccessException { |
1029 |
+ |
Field f = Unsafe.class.getDeclaredField("theUnsafe"); |
1030 |
+ |
f.setAccessible(true); |
1031 |
+ |
return (Unsafe) f.get(null); |
1032 |
+ |
} |
1033 |
+ |
|
1034 |
+ |
private static long fieldOffset(String fieldName) |
1035 |
+ |
throws NoSuchFieldException { |
1036 |
+ |
return _unsafe.objectFieldOffset |
1037 |
+ |
(ForkJoinTask.class.getDeclaredField(fieldName)); |
1038 |
+ |
} |
1039 |
|
|
1040 |
|
static final Unsafe _unsafe; |
1041 |
|
static final long statusOffset; |
1042 |
|
|
1043 |
|
static { |
1044 |
|
try { |
1045 |
< |
if (ForkJoinTask.class.getClassLoader() != null) { |
1046 |
< |
Field f = Unsafe.class.getDeclaredField("theUnsafe"); |
1047 |
< |
f.setAccessible(true); |
1048 |
< |
_unsafe = (Unsafe)f.get(null); |
1049 |
< |
} |
1014 |
< |
else |
1015 |
< |
_unsafe = Unsafe.getUnsafe(); |
1016 |
< |
statusOffset = _unsafe.objectFieldOffset |
1017 |
< |
(ForkJoinTask.class.getDeclaredField("status")); |
1018 |
< |
} catch (Exception ex) { throw new Error(ex); } |
1045 |
> |
_unsafe = getUnsafe(); |
1046 |
> |
statusOffset = fieldOffset("status"); |
1047 |
> |
} catch (Throwable e) { |
1048 |
> |
throw new RuntimeException("Could not initialize intrinsics", e); |
1049 |
> |
} |
1050 |
|
} |
1051 |
|
|
1052 |
|
} |