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,直到結果出來。(這種機制是為了更好地適應多線程環境)