Java多線程Thread , Future , Callable , FutureTask的使用
Thread創(chuàng)建一個線程
在想要使用多線程的技術來進行相應的操作的時候: 可以含有以下的方向來進行設計思考! 在創(chuàng)建一個線程的時候通常是創(chuàng)建一個Thread的。 但是這個Thread,是含有多種方式來進行創(chuàng)建操作的。 例如: 直接使用空參數(shù)的構造器進行創(chuàng)建操作:
System.out.println("start:" + System.currentTimeMillis());
Thread thread = new Thread();
thread.start();
System.out.println("end:" + System.currentTimeMillis());這樣執(zhí)行是沒有什么效果的。這種情況就是你啟動了一個線程,但是這個線程是沒有任何事情要干的。
時間是過的飛起的。
但是還有一種方法也是可以進行線程的啟動操作的。
使用含有參數(shù)方法的構造器進行創(chuàng)建線程:
System.out.println(Thread.currentThread() + "----start:" + System.currentTimeMillis());
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我正在執(zhí)行一個任務,不要打擾我!");
System.out.println(Thread.currentThread());
}
});
thread.start();
System.out.println(Thread.currentThread() + "----end:" + System.currentTimeMillis());這種是開啟一個線程讓其來進行線程任務的執(zhí)行操作的。
但是你有沒有發(fā)現(xiàn),這種方式有一點缺點的。
這個開啟的線程是相當于我要讓其進行一些子任務的執(zhí)行操作的。
Thread進行異步處理
類似于我是老師,我想讓學習委員去辦公室?guī)臀夷靡恍鴣淼?。此時學習委員已經出發(fā)了,但是我想起來我好像是帶了書的。我想要讓學習委員不要去辦公室拿書了。
若我直接采用這種方式來來進行執(zhí)行操作的話,是無法滿足我的需求的。只要是我叫他去拿書了,她就會喊不回來的。
那是否能對這種方式進行相應的改造操作呢???
java的開發(fā)者是給了我們一種實現(xiàn)的方式的。
使用Future的接口滿足需求。
相應的解釋:
A Future 表示異步計算的結果。提供了用于檢查計算是否完成、等待計算完成以及檢索計算結果的方法。只有在計算完成后才能使用方法 get 檢索結果,必要時會阻止,直到它準備就緒。取消是通過該 cancel 方法執(zhí)行的。提供了其他方法來確定任務是正常完成還是已取消。計算完成后,無法取消計算。如果為了可取消性而使用 a Future ,但不提供可用的結果,則可以聲明表單 Future<?> 的類型,并作為基礎任務的結果返回 null 。
public interface Future<V> {
?
/**
* Attempts to cancel execution of this task. This attempt will
* fail if the task has already completed, has already been cancelled,
* or could not be cancelled for some other reason. If successful,
* and this task has not started when {@code cancel} is called,
* this task should never run. If the task has already started,
* then the {@code mayInterruptIfRunning} parameter determines
* whether the thread executing this task should be interrupted in
* an attempt to stop the task.
*
* <p>After this method returns, subsequent calls to {@link #isDone} will
* always return {@code true}. Subsequent calls to {@link #isCancelled}
* will always return {@code true} if this method returned {@code true}.
*
* @param mayInterruptIfRunning {@code true} if the thread executing this
* task should be interrupted; otherwise, in-progress tasks are allowed
* to complete
* @return {@code false} if the task could not be cancelled,
* typically because it has already completed normally;
* {@code true} otherwise
*/
boolean cancel(boolean mayInterruptIfRunning);
?
/**
* Returns {@code true} if this task was cancelled before it completed
* normally.
*
* @return {@code true} if this task was cancelled before it completed
*/
boolean isCancelled();
?
/**
* Returns {@code true} if this task completed.
*
* Completion may be due to normal termination, an exception, or
* cancellation -- in all of these cases, this method will return
* {@code true}.
*
* @return {@code true} if this task completed
*/
boolean isDone();
?
/**
* Waits if necessary for the computation to complete, and then
* retrieves its result.
*
* @return the computed result
* @throws CancellationException if the computation was cancelled
* @throws ExecutionException if the computation threw an
* exception
* @throws InterruptedException if the current thread was interrupted
* while waiting
*/
V get() throws InterruptedException, ExecutionException;
?
/**
* Waits if necessary for at most the given time for the computation
* to complete, and then retrieves its result, if available.
*
* @param timeout the maximum time to wait
* @param unit the time unit of the timeout argument
* @return the computed result
* @throws CancellationException if the computation was cancelled
* @throws ExecutionException if the computation threw an
* exception
* @throws InterruptedException if the current thread was interrupted
* while waiting
* @throws TimeoutException if the wait timed out
*/
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}通過這個接口就可以實現(xiàn)相對應的功能操作了。
給予了一個接口想要將其進行實現(xiàn)操作就得要相關的實現(xiàn)類。
登場的就是FutureTask的類進行操作的。
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}執(zhí)行一下相關的代碼:
FutureTask<String> stringFutureTask = new FutureTask<String>(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我正在執(zhí)行一個任務,不要打擾我!");
System.out.println(Thread.currentThread());
}
} , null);
?
Thread futureThread = new Thread(stringFutureTask);
futureThread.start();
// 是可以滿足對一個進行任務的取消工作的
// stringFutureTask.cancel(true);
System.out.println(stringFutureTask.isCancelled());
?
?
Thread futureThread1 = new Thread(stringFutureTask);
futureThread1.start();第二個 futureThread1 是不會執(zhí)行的。
解釋原因:
在Java中,FutureTask只能執(zhí)行一次。當您嘗試第二次執(zhí)行相同的FutureTask實例時,它不會執(zhí)行任何操作。這是因為FutureTask的狀態(tài)在第一次執(zhí)行后會改變,它不會重新開始。如果第一個線程(futureThread)已經開始執(zhí)行stringFutureTask,那么第二個線程(futureThread1)嘗試開始相同的stringFutureTask時,將不會有任何效果,因為FutureTask的狀態(tài)已經不是初始狀態(tài)了。
這里是一些關鍵點:
FutureTask在執(zhí)行后會進入完成狀態(tài)。如果嘗試再次執(zhí)行一個已經完成的
FutureTask,它不會重新執(zhí)行。如果需要重新執(zhí)行任務,您需要創(chuàng)建一個新的
FutureTask實例。
上面相關的例子,已經將一個老師叫學習委員去辦公室拿書的例子叫停了。也就是說現(xiàn)在是實現(xiàn)了異步處理的操作。
帶有參數(shù)的返回線程處理
我現(xiàn)在還有一個需求,是干嘛的呢???我不是喊學習委員去辦公室拿書了嗎??我想要那個他拿到的書給我手上。這個功能是怎么實現(xiàn)的呢?
也就是含有返回值的相關的例子?。?!
JUC給了一個方法,是可以直接將一個Callable的接口傳過來的
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}使用這個接口作為參數(shù)傳給的FutureTask進行任務的初始化操作。
我們知道Callable接口是有返回值的。那么就可以類似于得到相應的那一本書了?。?!
操作實現(xiàn):
FutureTask<String> stringFutureTask = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我正在執(zhí)行一個任務,不要打擾我!");
return "老師,我拿到書了";
}
});
?
Thread thread = new Thread(stringFutureTask);
thread.start();
System.out.println(stringFutureTask.get());將得到的東西進行返回操作。這樣的話就可以實現(xiàn)三種基本的功能操作了。
到此這篇關于Java多線程Thread , Future , Callable , FutureTask的使用的文章就介紹到這了,更多相關Java Thread , Future , Callable , FutureTask內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- Java中關于ThreadLocal的隱式引用詳解
- Java中的Random和ThreadLocalRandom詳細解析
- Java中的ThreadLocal源碼及弱引用解析
- Java中ThreadLocal共享變量的使用
- Java中的ScheduledThreadPoolExecutor定時任務詳解
- Java中的FutureTask實現(xiàn)代碼實例
- Java中的FutureTask源碼解析
- 一文搞懂Runnable、Callable、Future、FutureTask及應用
- Java并發(fā)編程中的Callable、Future和FutureTask詳解
- Java中Future和FutureTask的示例詳解及使用
- Java多線程 Callable、Future 和FutureTask
相關文章
springboot集成本地緩存Caffeine的三種使用方式(小結)
本文主要介紹了springboot集成本地緩存Caffeine的三種使用方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-06-06
SpringBoot定時任務兩種(Spring Schedule 與 Quartz 整合 )實現(xiàn)方法
本篇文章主要介紹了SpringBoot定時任務兩種(Spring Schedule 與 Quartz 整合 )實現(xiàn)方法,詳細的介紹了Spring Schedule 與 Quartz 整合的兩種方法,有興趣的可以了解一下。2017-03-03
使用Spring AOP實現(xiàn)MySQL數(shù)據庫讀寫分離案例分析(附demo)
分布式環(huán)境下數(shù)據庫的讀寫分離策略是解決數(shù)據庫讀寫性能瓶頸的一個關鍵解決方案,這篇文章主要介紹了使用Spring AOP實現(xiàn)MySQL數(shù)據庫讀寫分離案例分析(附demo),有興趣的可以了解一下。2017-01-01

