();
}
/**
@@ -106,8 +106,6 @@ public abstract class QueueUtil {
/**
* 支持后进先出的并发栈,用ConcurrentLinkedDeque实现,经过Collections#asLifoQueue()转换顺序
*
- * 兼容了JDK6
- *
* 另对于BlockingQueue接口, JDK暂无Lifo倒转实现,因此只能直接使用未调转顺序的LinkedBlockingDeque
*
* @see Collections#asLifoQueue()
diff --git a/modules/utils/src/main/java/org/springside/modules/utils/concurrent/jsr166e/RecursiveAction.java b/modules/utils/src/main/java/org/springside/modules/utils/concurrent/jsr166e/RecursiveAction.java
new file mode 100644
index 00000000..05b8c40f
--- /dev/null
+++ b/modules/utils/src/main/java/org/springside/modules/utils/concurrent/jsr166e/RecursiveAction.java
@@ -0,0 +1,166 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package org.springside.modules.utils.concurrent.jsr166e;
+
+/**
+ * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/RecursiveAction.java 1.3
+ *
+ * A recursive resultless {@link ForkJoinTask}. This class
+ * establishes conventions to parameterize resultless actions as
+ * {@code Void} {@code ForkJoinTask}s. Because {@code null} is the
+ * only valid value of type {@code Void}, methods such as {@code join}
+ * always return {@code null} upon completion.
+ *
+ * Sample Usages. Here is a simple but complete ForkJoin
+ * sort that sorts a given {@code long[]} array:
+ *
+ *
{@code
+ * static class SortTask extends RecursiveAction {
+ * final long[] array; final int lo, hi;
+ * SortTask(long[] array, int lo, int hi) {
+ * this.array = array; this.lo = lo; this.hi = hi;
+ * }
+ * SortTask(long[] array) { this(array, 0, array.length); }
+ * protected void compute() {
+ * if (hi - lo < THRESHOLD)
+ * sortSequentially(lo, hi);
+ * else {
+ * int mid = (lo + hi) >>> 1;
+ * invokeAll(new SortTask(array, lo, mid),
+ * new SortTask(array, mid, hi));
+ * merge(lo, mid, hi);
+ * }
+ * }
+ * // implementation details follow:
+ * static final int THRESHOLD = 1000;
+ * void sortSequentially(int lo, int hi) {
+ * Arrays.sort(array, lo, hi);
+ * }
+ * void merge(int lo, int mid, int hi) {
+ * long[] buf = Arrays.copyOfRange(array, lo, mid);
+ * for (int i = 0, j = lo, k = mid; i < buf.length; j++)
+ * array[j] = (k == hi || buf[i] < array[k]) ?
+ * buf[i++] : array[k++];
+ * }
+ * }}
+ *
+ * You could then sort {@code anArray} by creating {@code new
+ * SortTask(anArray)} and invoking it in a ForkJoinPool. As a more
+ * concrete simple example, the following task increments each element
+ * of an array:
+ * {@code
+ * class IncrementTask extends RecursiveAction {
+ * final long[] array; final int lo, hi;
+ * IncrementTask(long[] array, int lo, int hi) {
+ * this.array = array; this.lo = lo; this.hi = hi;
+ * }
+ * protected void compute() {
+ * if (hi - lo < THRESHOLD) {
+ * for (int i = lo; i < hi; ++i)
+ * array[i]++;
+ * }
+ * else {
+ * int mid = (lo + hi) >>> 1;
+ * invokeAll(new IncrementTask(array, lo, mid),
+ * new IncrementTask(array, mid, hi));
+ * }
+ * }
+ * }}
+ *
+ * The following example illustrates some refinements and idioms
+ * that may lead to better performance: RecursiveActions need not be
+ * fully recursive, so long as they maintain the basic
+ * divide-and-conquer approach. Here is a class that sums the squares
+ * of each element of a double array, by subdividing out only the
+ * right-hand-sides of repeated divisions by two, and keeping track of
+ * them with a chain of {@code next} references. It uses a dynamic
+ * threshold based on method {@code getSurplusQueuedTaskCount}, but
+ * counterbalances potential excess partitioning by directly
+ * performing leaf actions on unstolen tasks rather than further
+ * subdividing.
+ *
+ *
{@code
+ * double sumOfSquares(ForkJoinPool pool, double[] array) {
+ * int n = array.length;
+ * Applyer a = new Applyer(array, 0, n, null);
+ * pool.invoke(a);
+ * return a.result;
+ * }
+ *
+ * class Applyer extends RecursiveAction {
+ * final double[] array;
+ * final int lo, hi;
+ * double result;
+ * Applyer next; // keeps track of right-hand-side tasks
+ * Applyer(double[] array, int lo, int hi, Applyer next) {
+ * this.array = array; this.lo = lo; this.hi = hi;
+ * this.next = next;
+ * }
+ *
+ * double atLeaf(int l, int h) {
+ * double sum = 0;
+ * for (int i = l; i < h; ++i) // perform leftmost base step
+ * sum += array[i] * array[i];
+ * return sum;
+ * }
+ *
+ * protected void compute() {
+ * int l = lo;
+ * int h = hi;
+ * Applyer right = null;
+ * while (h - l > 1 && getSurplusQueuedTaskCount() <= 3) {
+ * int mid = (l + h) >>> 1;
+ * right = new Applyer(array, mid, h, right);
+ * right.fork();
+ * h = mid;
+ * }
+ * double sum = atLeaf(l, h);
+ * while (right != null) {
+ * if (right.tryUnfork()) // directly calculate if not stolen
+ * sum += right.atLeaf(right.lo, right.hi);
+ * else {
+ * right.join();
+ * sum += right.result;
+ * }
+ * right = right.next;
+ * }
+ * result = sum;
+ * }
+ * }}
+ *
+ * @since 1.7
+ * @author Doug Lea
+ */
+public abstract class RecursiveAction extends ForkJoinTask {
+ private static final long serialVersionUID = 5232453952276485070L;
+
+ /**
+ * The main computation performed by this task.
+ */
+ protected abstract void compute();
+
+ /**
+ * Always returns {@code null}.
+ *
+ * @return {@code null} always
+ */
+ public final Void getRawResult() { return null; }
+
+ /**
+ * Requires null completion value.
+ */
+ protected final void setRawResult(Void mustBeNull) { }
+
+ /**
+ * Implements execution conventions for RecursiveActions.
+ */
+ protected final boolean exec() {
+ compute();
+ return true;
+ }
+
+}
diff --git a/modules/utils/src/main/java/org/springside/modules/utils/concurrent/jsr166e/RecursiveTask.java b/modules/utils/src/main/java/org/springside/modules/utils/concurrent/jsr166e/RecursiveTask.java
new file mode 100644
index 00000000..4481585c
--- /dev/null
+++ b/modules/utils/src/main/java/org/springside/modules/utils/concurrent/jsr166e/RecursiveTask.java
@@ -0,0 +1,71 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package org.springside.modules.utils.concurrent.jsr166e;
+
+/**
+ * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/RecursiveTask.java 1.4
+ *
+ * A recursive result-bearing {@link ForkJoinTask}.
+ *
+ * For a classic example, here is a task computing Fibonacci numbers:
+ *
+ *
{@code
+ * class Fibonacci extends RecursiveTask {
+ * final int n;
+ * Fibonacci(int n) { this.n = n; }
+ * protected Integer compute() {
+ * if (n <= 1)
+ * return n;
+ * Fibonacci f1 = new Fibonacci(n - 1);
+ * f1.fork();
+ * Fibonacci f2 = new Fibonacci(n - 2);
+ * return f2.compute() + f1.join();
+ * }
+ * }}
+ *
+ * However, besides being a dumb way to compute Fibonacci functions
+ * (there is a simple fast linear algorithm that you'd use in
+ * practice), this is likely to perform poorly because the smallest
+ * subtasks are too small to be worthwhile splitting up. Instead, as
+ * is the case for nearly all fork/join applications, you'd pick some
+ * minimum granularity size (for example 10 here) for which you always
+ * sequentially solve rather than subdividing.
+ *
+ * @since 1.7
+ * @author Doug Lea
+ */
+public abstract class RecursiveTask extends ForkJoinTask {
+ private static final long serialVersionUID = 5232453952276485270L;
+
+ /**
+ * The result of the computation.
+ */
+ V result;
+
+ /**
+ * The main computation performed by this task.
+ * @return the result of the computation
+ */
+ protected abstract V compute();
+
+ public final V getRawResult() {
+ return result;
+ }
+
+ protected final void setRawResult(V value) {
+ result = value;
+ }
+
+ /**
+ * Implements execution conventions for RecursiveTask.
+ */
+ protected final boolean exec() {
+ result = compute();
+ return true;
+ }
+
+}
diff --git a/modules/utils/src/main/java/org/springside/modules/utils/io/IOUtil.java b/modules/utils/src/main/java/org/springside/modules/utils/io/IOUtil.java
index 5e5e1593..bd4c51fa 100644
--- a/modules/utils/src/main/java/org/springside/modules/utils/io/IOUtil.java
+++ b/modules/utils/src/main/java/org/springside/modules/utils/io/IOUtil.java
@@ -8,10 +8,8 @@ import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
-import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
-import java.util.zip.ZipFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,32 +58,6 @@ public abstract class IOUtil {
}
}
- /**
- * For JDK6 which ZipFile is not Closeable.
- */
- public static void closeQuietly(ZipFile zipfile) {
- if (zipfile != null) {
- try {
- zipfile.close();
- } catch (IOException e) {
- logger.warn(CLOSE_ERROR_MESSAGE, e);
- }
- }
- }
-
- /**
- * For JDK6 which Socket is not Closeable.
- */
- public static void closeQuietly(Socket socket) {
- if (socket != null) {
- try {
- socket.close();
- } catch (IOException e) {
- logger.warn(CLOSE_ERROR_MESSAGE, e);
- }
- }
- }
-
/**
* 简单读取InputStream到String.
*/
diff --git a/modules/utils/src/main/java/org/springside/modules/utils/number/RandomUtil.java b/modules/utils/src/main/java/org/springside/modules/utils/number/RandomUtil.java
index 4ca2a4f8..c561ff68 100644
--- a/modules/utils/src/main/java/org/springside/modules/utils/number/RandomUtil.java
+++ b/modules/utils/src/main/java/org/springside/modules/utils/number/RandomUtil.java
@@ -11,14 +11,12 @@ import org.springside.modules.utils.base.MoreValidate;
/**
* 随机数工具集.
*
- * 1. 获取无锁的兼容JDK6的ThreadLocalRandom
+ * 1. 获取无锁的ThreadLocalRandom, 性能较佳的SecureRandom
*
- * 2. 获取性能较佳的SecureRandom
- *
- * 3. 保证没有负数陷阱,也能更精确设定范围的nextInt/nextLong/nextDouble (copy from Common Lang
+ * 2. 保证没有负数陷阱,也能更精确设定范围的nextInt/nextLong/nextDouble (copy from Common Lang
* RandomUtils,但默认使用性能较优的ThreadLocalRandom,并可配置其他的Random)
*
- * 4. 随机字符串
+ * 3. 随机字符串
*
* @author calvin
*/
@@ -27,8 +25,6 @@ public abstract class RandomUtil {
/////////////////// 获取Random实例//////////////
/**
* 返回无锁的ThreadLocalRandom
- *
- * 如果JDK6,使用移植于jsr166e的版本(相当于JDK7的实现)
*/
public static Random threadLocalRandom() {
return java.util.concurrent.ThreadLocalRandom.current();