并发包 Future 解读
java 并发包 java.util.concurrent 有很多关于并发编程相关的类
屏蔽了操作系统的调度 友好的提供了API 便于技术大大更高效 快捷的使用多核心 提高应用的响应耗时 提升性能
Future 官方文档
future 是一个 异步计算的类。提供了检查计算是否完成、等待其完成并检索计算结果的方法。
应用场景
应用中的列表查询 是一个很常见的业务场景.一般来说 会有2种查询
1.查询当前分页的数据
2.查询当前条件的数据总数 计算分页
常用的写法就是
ex:
List result = queryList(params);
int count = queryListCount(params);
这里很明显是个串行的操作.如果都是耗时的操作 那么整个请求的耗时就是2个查询的叠加
那么 如果使用Future 异步方式呢.
那么时间耗时 就不是串行的操作 而是个并行的操作.
ex:
/* 启动一个新的线程去执行 /
Future future = Executors.newFixedThreadPool().submit(new Callback()
public String call() {
return queryListCount(params);
});
/* 主线程执行 /
List result = queryList(params);
int count = future.get(time,TimeUnit);
这样的话 就能减小整个请求的耗时
Future 是怎么做到的?
Future 只是个接口 常用的实现类是 FutureTask java.util.concurrent 包下面的
public class FutureTask<V> implements RunnableFuture<V> {
/** 只贴出比较重要的方法 */
public void run() {
/** 判断当前执行状态 */
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
/** 线程等待处理完成 */
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
/** 如果处理完成 就回写结果 */
if (ran)
set(result);
}
} finally {
// runner must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
/**
* 获取数据操作时候 一直进行cas操作 判断任务状态
*/
public V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
if (unit == null)
throw new NullPointerException();
int s = state;
if (s <= COMPLETING &&
/** 阻塞线程 */
(s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
throw new TimeoutException();
return report(s);
}
/**
* run 方法执行完成 会通过set方法给outcome 赋值
*/
private V report(int s) throws ExecutionException {
Object x = outcome;
if (s == NORMAL)
return (V)x;
if (s >= CANCELLED)
throw new CancellationException();
throw new ExecutionException((Throwable)x);
}
/**
* 利用CAS操作 阻塞线程 返回当前任务状态
*
*/
private int awaitDone(boolean timed, long nanos)
throws InterruptedException {
final long deadline = timed ? System.nanoTime() + nanos : 0L;
WaitNode q = null;
boolean queued = false;
/** 死循环 一直尝试获取state状态 */
for (;;) {
if (Thread.interrupted()) {
removeWaiter(q);
throw new InterruptedException();
}
int s = state;
if (s > COMPLETING) {
if (q != null)
q.thread = null;
return s;
}
/** 如果状态完成 就让出线程占用的硬件资源 */
else if (s == COMPLETING) // cannot time out yet
Thread.yield();
else if (q == null)
q = new WaitNode();
else if (!queued)
queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
q.next = waiters, q);
else if (timed) {
/** 如果等待时间消耗完了 就直接返回了 */
nanos = deadline - System.nanoTime();
if (nanos <= 0L) {
removeWaiter(q);
return state;
}
/** 线程阻塞nanos毫秒 */
LockSupport.parkNanos(this, nanos);
}
else
/** 线程一直阻塞 */
LockSupport.park(this);
}
}
}