futurejava
1. java.util.concurrent.Future.isDone是否有必要
有必要,因为get方法会一直等待资源返回,可以用isDone判断
Future.get()方法会一直阻塞,直到有数据返回,这时候isDone()是true.那么在get()之前判断isDone()是否有必要?如下:
if (!future.isCancelled())
{
HotelSearchResponse response = null;
if (future.isDone()) //这里有没有必要判断
{
if (future.get() != null)
{
response = future.get();
}
else
{
while (!future.isDone())//这个while有没有必要
{
if (future.get() != null)
{
response = future.get();
}
}
}
}
2. java future如何强制终止
future 咱写的。
3. java多线程中的callable和future常用在哪些地方
运行Callable任务可以拿到一个Future对象,表示异步计算的结果。
用于Java多线程开发
工具/原料
Java IDE
方法/步骤
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallableTest{
public static void main(String [] args ) {
String [] words = {"first","second","world","thread"};
ExecutorService pool = Executors.newCachedThreadPool();
Set<Future<Integer>> set = new HashSet<Future<Integer>>();
for (String word:words) {
Callable callable = new testCallable(word);
Future future = pool.submit(callable);
set.add(future);
}
int sum = 0;
for (Future future:set) {
try {
sum += (int)future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
System.out.println("数组中所有单词的总长度为:" + sum);
}
}
class testCallable implements Callable{
private String word;
public testCallable(String word){
this.word = word;
}
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName() + ": 开始执行" );
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ": 正在处理" );
System.out.println(Thread.currentThread().getName() + ": " + word + "长度为:" + word.length());
return Integer.valueOf(word.length());
}
}
pool-1-thread-2: 开始执行
pool-1-thread-4: 开始执行
pool-1-thread-3: 开始执行
pool-1-thread-1: 开始执行
pool-1-thread-1: 正在处理
pool-1-thread-1: first长度为:5
pool-1-thread-3: 正在处理
pool-1-thread-3: world长度为:5
pool-1-thread-2: 正在处理
pool-1-thread-2: second长度为:6
pool-1-thread-4: 正在处理
pool-1-thread-4: thread长度为:6
数组中所有单词的总长度为:22
4. 什么是java future模式
Future介绍
用过Java并发包的朋友或许对Future (interface) 已经比较熟悉了,其实Future 本身是一种被广泛运用的并发设计模式,可在很大程度上简化需要数据流同步的并发应用开发。
Future模式可以简单的看成是 Proxy 模式 与 Thread-Per-Message 模式 的结合,在Proxy模式中,用一个Proxy来代替真正的目标(Subject)生成,目标的生成可能是费时的,例如在开启一个内嵌图片的文件中,希望程式能尽快完成开启文件的动作,并显示一个可接受的画面给使用者看,在还不需要看到图片的页面中先使用Proxy代替真正的图片载入,只有在真正需要看到图片时,才由Proxy物件载入真正的图片。
考虑这样一个情况,使用者可能快速翻页浏览文件中,而图片档案很大,如此在浏览到有图片的页数时,就会导致图片的载入,因而造成使用者浏览文件时会有停顿的现象,所以我们希望在文件开启之后,仍有一个背景作业持续载入图片,如此使用者在快速浏览页面时,所造成的停顿可以获得改善。
Future模式在请求发生时,会先产生一个Future物件给发出请求的客户,它的作用就像是Proxy物件,而同时间,真正的目标物件之生成,由一个新的执行绪持续进行(即Thread-Per-Message),真正的目标物件生成之后,将之设定至Future之中,而当客户端真正需要目标物件时,目标物件也已经准备好,可以让客户提取使用。
这里就以java.util.concurrent.Future 为例简单说一下Future的具体工作方式。Future对象本身可以看作是一个显式的引用,一个对异步处理结果的引用。由于其异步性质,在创建之初,它所引用的对象可能还并不可用(比如尚在运算中,网络传输中或等待中)。这时,得到Future的程序流程如果并不急于使用Future所引用的对象,那么它可以做其它任何想做的事儿,当流程进行到需要Future背后引用的对象时,可能有两种情况:
希望能看到这个对象可用,并完成一些相关的后续流程。如果实在不可用,也可以进入其它分支流程。
“没有你我的人生就会失去意义,所以就算海枯石烂,我也要等到你。”(当然,如果实在没有毅力枯等下去,设一个超时也是可以理解的)
5. 为什么并发包抽出了runnablefuture接口 java
最近也在看Java并发框架,Callable 、Future、RunnableFuture、FutureTask、Sync、ThreadPoolExecutor等类可以放在一起研究,重点关注callbale接口返回对象以及对线程相关操作的处理上。
要注意:RunnableFuture接口是继承了Runnable和Future接口的
package java.util.concurrent;
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
package java.lang;
public
interface Runnable {
public abstract void run();
}
在我们调用ThreadPoolExecutor当中的submit方法的时候
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Object> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
其实该方法是有三个重载的,既可以submit Callable对象也可以submit Runnable对象 也可以submit Runnable对象同时附加返回值。
而FutureTask对象是RunnableFuture接口的实现
public class FutureTask<V> implements RunnableFuture<V>
注意,在submit的时候线程池最终还是调用的ThreadPoolExecutor的execute(Runnable runnable)方法实现的,因此我们是将Callable对象封装在FutureTask对象当中,由于FutureTask对象实现了RunnableFuture接口,也是个Runnable对象,最后返回的也是这个FutureTask对象。
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
关键就是在于生成的FutureTask对象的额run方法开始。
package java.util.concurrent;
import java.util.concurrent.locks.*;
public class FutureTask<V> implements RunnableFuture<V> {
private final Sync sync;
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
sync = new Sync(callable);
}
public FutureTask(Runnable runnable, V result) {
sync = new Sync(Executors.callable(runnable, result));
}
public boolean isCancelled() {
return sync.innerIsCancelled();
}
public boolean isDone() {
return sync.innerIsDone();
}
public boolean cancel(boolean mayInterruptIfRunning) {
return sync.innerCancel(mayInterruptIfRunning);
}
/**
* @throws CancellationException {@inheritDoc}
*/
public V get() throws InterruptedException, ExecutionException {
return sync.innerGet();
}
public V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return sync.innerGet(unit.toNanos(timeout));
}
protected void done() { }
protected void set(V v) {
sync.innerSet(v);
}
protected void setException(Throwable t) {
sync.innerSetException(t);
}
public void run() {
sync.innerRun();
}
protected boolean runAndReset() {
return sync.innerRunAndReset();
}
private final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -7828117401763700385L;
private static final int RUNNING = 1;
private static final int RAN = 2;
private static final int CANCELLED = 4;
private final Callable<V> callable;
private V result;
private Throwable exception;
private volatile Thread runner;
Sync(Callable<V> callable) {
this.callable = callable;
}
private boolean ranOrCancelled(int state) {
return (state & (RAN | CANCELLED)) != 0;
}
/**
* Implements AQS base acquire to succeed if ran or cancelled
*/
protected int tryAcquireShared(int ignore) {
return innerIsDone()? 1 : -1;
}
protected boolean tryReleaseShared(int ignore) {
runner = null;
return true;
}
boolean innerIsCancelled() {
return getState() == CANCELLED;
}
boolean innerIsDone() {
return ranOrCancelled(getState()) && runner == null;
}
V innerGet() throws InterruptedException, ExecutionException {
acquireSharedInterruptibly(0);
if (getState() == CANCELLED)
throw new CancellationException();
if (exception != null)
throw new ExecutionException(exception);
return result;
}
V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException {
if (!tryAcquireSharedNanos(0, nanosTimeout))
throw new TimeoutException();
if (getState() == CANCELLED)
throw new CancellationException();
if (exception != null)
throw new ExecutionException(exception);
return result;
}
void innerSet(V v) {
for (;;) {
int s = getState();
if (s == RAN)
return;
if (s == CANCELLED) {
// aggressively release to set runner to null,
// in case we are racing with a cancel request
// that will try to interrupt runner
releaseShared(0);
return;
}
if (compareAndSetState(s, RAN)) {
result = v;
releaseShared(0);
done();
return;
}
}
}
void innerSetException(Throwable t) {
for (;;) {
int s = getState();
if (s == RAN)
return;
if (s == CANCELLED) {
releaseShared(0);
return;
}
if (compareAndSetState(s, RAN)) {
exception = t;
result = null;
releaseShared(0);
done();
return;
}
}
}
boolean innerCancel(boolean mayInterruptIfRunning) {
for (;;) {
int s = getState();
if (ranOrCancelled(s))
return false;
if (compareAndSetState(s, CANCELLED))
break;
}
if (mayInterruptIfRunning) {
Thread r = runner;
if (r != null)
r.interrupt();
}
releaseShared(0);
done();
return true;
}
void innerRun() {
if (!compareAndSetState(0, RUNNING))
return;
try {
runner = Thread.currentThread();
if (getState() == RUNNING) // recheck after setting thread
innerSet(callable.call());
else
releaseShared(0); // cancel
} catch (Throwable ex) {
innerSetException(ex);
}
}
boolean innerRunAndReset() {
if (!compareAndSetState(0, RUNNING))
return false;
try {
runner = Thread.currentThread();
if (getState() == RUNNING)
callable.call(); // don't set result
runner = null;
return compareAndSetState(RUNNING, 0);
} catch (Throwable ex) {
innerSetException(ex);
return false;
}
}
}
}
不知道知乎能让写多长,代码粘贴了那么多。
已知的情报:
① sync是FutureTask中的内部类,
private final Sync sync;
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
sync = new Sync(callable);
}
private final class Sync extends AbstractQueuedSynchronizer
AbstractQueuedSynchronizer的中文名字叫做同步器,一种说法:是用来控制资源占用的同步器,对于FutureTask来说,就是控制返回值result的这个资源的访问来决定是否需要马上取得result的结果,当超时时间未到,或者线程未执行结束的时候,是不能去取result的,当线程正常执行结束后,一系列的标志位会被修改,并告诉等待future执行结果的各个线程,可以来获取result了。
(1)
public void run() {
sync.innerRun();
}
Executors的线程池执行这个run()方法
()
6. java future函数的作用
submit 一个请求之后,你可以在 future.get() 上阻塞等待也可以有一个 while 循环,不停地 future.isDone() 再检测是否任务完成,如果完成再来 future.get() 就立马得到结果了。
7. java协程和futuretask的区别
Callable要采用ExecutorSevice的submit方法提交,返回Future对象,通过Future的get()方法,同步拿到线程的返回结果,实例代码如下:
public class ThreadExample12 { public static void main(String[] args) {
ExecutorService threadPool = Executors.newSingleThreadExecutor();
Future<String> future = threadPool.submit(new Callable<String>() { public String call() throws Exception {
Thread.sleep(2000); return "Hello World";
};
});
System.out.println("等待结果"); try {
System.out.println("返回结果为:" + future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Future取得的结果类型和Callable返回的结果类型必须一致,这是通过泛型来实现的。Callable要采用ExecutorSevice的submit方法提交,返回的Future对象可以取消任务,通过调用Future的future.cancel(true)方法实现,Future对象还可以对超时线程进行关闭,通过future.wait(3);如果线程耗时超过3秒则抛出异常
在这里有人可能会有疑问,既然要同步返回结果,那我为什么要再开一个线程去执行呢,还不如直接在主线程执行就好。但是这种是局限于在一个线程时,如果需要同时执行多个线程,等待多个线程返回结果时,在主线程中是不能实现这种功能的。可以看一下实例代码,就能明白了:
public class ThreadExample13 { public static void main(String[] args) {
ExecutorService threadPool = Executors.newFixedThreadPool(10);
CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool); for (int i = 1; i <= 10; i++) {
final int seq = i;
completionService.submit(new Callable<Integer>() {
@Override public Integer call() throws Exception {
Thread.sleep(new Random().nextInt(5000)); return seq;
}
});
} for (int i = 0; i < 10; i++) { try {
System.out.println(completionService.take().get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
8. java中文futuretask什么区别
FutureTask是Future的一个基础实现,可以将它同Executors使用处理异步任务。通常不需要使用FutureTask类,单当打算重写Future接口的一些方法并保持原来基础的实现是,它就变得非常有用。
9. 求大神,Java自带的Future多线程模式是什么意思
理1:
什么是Future?
用过Java并发包的朋友或许对Future (interface) 已经比较熟悉了,其实Future
本身是一种被广泛运用的并发设计模式,可在很大程度上简化需要数据流同步的并发应用开发。在一些领域语言(如Alice ML
)中甚至直接于语法层面支持Future。
这里就以java.util.concurrent.Future
为例简单说一下Future的具体工作方式。Future对象本身可以看作是一个显式的引用,一个对异步处理结果的引用。由于其异步性质,在创建之初,它
所引用的对象可能还并不可用(比如尚在运算中,网络传输中或等待中)。这时,得到Future的程序流程如果并不急于使用Future所引用的对象,那么
它可以做其它任何想做的事儿,当流程进行到需要Future背后引用的对象时,可能有两种情况:
希望能看到这个对象可用,并完成一些相关的后续流程。如果实在不可用,也可以进入其它分支流程。
“没有你我的人生就会失去意义,所以就算海枯石烂,我也要等到你。”(当然,如果实在没有毅力枯等下去,设一个超时也是可以理解的)
对于前一种情况,可以通过调用Future.isDone()判断引用的对象是否就绪,并采取不同的处理;而后一种情况则只需调用get()或
get(long timeout, TimeUnit unit)通过同步阻塞方式等待对象就绪。实际运行期是阻塞还是立即返回就取决于get()的调用时机和对象就绪的先后了。
整理二:
什么是Future模式呢?Future
顾名思义,在金融行业叫期权,市场上有看跌期权和看涨期权,你可以在现在(比如九月份)购买年底(十二月)的石油,假如你买的是看涨期权,那么如果石油真
的涨了,你也可以在十二月份依照九月份商定的价格购买。扯远了,Future就是你可以拿到未来的结果。对于多线程,如果线程A要等待线程B的结果,那么
线程A没必要等待B,直到B有结果,可以先拿到一个未来的Future,等B有结果是再取真实的结果。其实这个模式用的很多,比如浏览器下载图片的时候,
刚开始是不是通过模糊的图片来代替最后的图片,等下载图片的线程下载完图片后在替换。
补充:
当另外一个线程需要使用某一个线程的结果时,可以通过Future引用的get()方法去获得,如果结果还未出来,调用此方法的线程被block,直到结果出来。(这种机制是为了更好地适应多线程环境)