#539 JDK依赖改为JDK7.0+
This commit is contained in:
@@ -4,11 +4,13 @@ jdk:
|
||||
|
||||
install: true
|
||||
script:
|
||||
- "cd modules;mvn clean test"
|
||||
- jdk_switcher use oraclejdk8
|
||||
- "mvn test"
|
||||
- "cd modules;mvn clean test"
|
||||
- jdk_switcher use oraclejdk8
|
||||
- "mvn clean test"
|
||||
- mvn clean package -Dmaven.test.skip=true
|
||||
- jdk_switcher use oraclejdk7
|
||||
- "mvn test"
|
||||
- "mvn clean package -Dmaven.test.skip=true"
|
||||
- jdk_switcher use oraclejdk7
|
||||
- "mvn test"
|
||||
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
<slf4j.version>1.7.22</slf4j.version>
|
||||
<logback.version>1.1.8</logback.version>
|
||||
<junit.version>4.12</junit.version>
|
||||
<assertj.version>2.2.0</assertj.version>
|
||||
<assertj.version>2.6.0</assertj.version>
|
||||
<mockito.version>1.10.19</mockito.version>
|
||||
|
||||
<!-- Plugin的属性 -->
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.6</java.version>
|
||||
<java.version>1.7</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
<!-- Plugin的属性 -->
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.6</java.version>
|
||||
<java.version>1.7</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
@@ -4,7 +4,6 @@ import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.springside.modules.utils.base.SystemPropertiesUtil.PropertiesListener;
|
||||
import org.springside.modules.utils.number.NumberUtil;
|
||||
|
||||
/**
|
||||
@@ -198,7 +197,6 @@ public class SystemPropertiesUtil {
|
||||
* Properties 本质上是一个HashTable,每次读写都会加锁,所以不支持频繁的System.getProperty(name)来检查系统内容变化 因此扩展了一个ListenableProperties,
|
||||
* 在其所关心的属性变化时进行通知.
|
||||
*
|
||||
* @see PropertiesUtil#registerSystemPropertiesListener(PropertiesListener)
|
||||
* @see PropertiesListener
|
||||
*/
|
||||
public static class ListenableProperties extends Properties {
|
||||
|
||||
@@ -45,10 +45,10 @@ public abstract class QueueUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建无阻塞情况下,性能最优的并发双端队列 (兼容JDK6的情况)
|
||||
* 创建无阻塞情况下,性能最优的并发双端队列
|
||||
*/
|
||||
public static <E> Deque<E> newConcurrentNonBlockingDeque() {
|
||||
return new java.util.concurrent.ConcurrentLinkedDeque<E>();
|
||||
return new java.util.concurrent.ConcurrentLinkedDeque<E>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,8 +106,6 @@ public abstract class QueueUtil {
|
||||
/**
|
||||
* 支持后进先出的并发栈,用ConcurrentLinkedDeque实现,经过Collections#asLifoQueue()转换顺序
|
||||
*
|
||||
* 兼容了JDK6
|
||||
*
|
||||
* 另对于BlockingQueue接口, JDK暂无Lifo倒转实现,因此只能直接使用未调转顺序的LinkedBlockingDeque
|
||||
*
|
||||
* @see Collections#asLifoQueue()
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
* <p><b>Sample Usages.</b> Here is a simple but complete ForkJoin
|
||||
* sort that sorts a given {@code long[]} array:
|
||||
*
|
||||
* <pre> {@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++];
|
||||
* }
|
||||
* }}</pre>
|
||||
*
|
||||
* 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:
|
||||
* <pre> {@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));
|
||||
* }
|
||||
* }
|
||||
* }}</pre>
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <pre> {@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;
|
||||
* }
|
||||
* }}</pre>
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Doug Lea
|
||||
*/
|
||||
public abstract class RecursiveAction extends ForkJoinTask<Void> {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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}.
|
||||
*
|
||||
* <p>For a classic example, here is a task computing Fibonacci numbers:
|
||||
*
|
||||
* <pre> {@code
|
||||
* class Fibonacci extends RecursiveTask<Integer> {
|
||||
* 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();
|
||||
* }
|
||||
* }}</pre>
|
||||
*
|
||||
* 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<V> extends ForkJoinTask<V> {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user