一、線程創(chuàng)建方式
1.繼承Thread類,重寫run方法
2.實現(xiàn)Runnable接口,實現(xiàn)run方法
相較于繼承Thread類方式可以避免單繼承局限
3.實現(xiàn)Callable接口,實現(xiàn)call方法
相較于實現(xiàn)Runnable接口,Callable接口提供了返回值的功能,一般配合Future接口使用,可以在任務(wù)執(zhí)行完畢之后得到任務(wù)執(zhí)行結(jié)果
4.通過線程池啟動多線程
二、線程常用接口介紹
1.Future
Future接口為具體的Runnable或Callable任務(wù)提供了取消任務(wù),查詢?nèi)蝿?wù)狀態(tài),獲取任務(wù)結(jié)果的功能,可以通過get()方法獲取執(zhí)行結(jié)果,該方法會阻塞直到任務(wù)返回結(jié)果
api:
cancel:
取消任務(wù)方法,取消成功返回true,失敗返回false。參數(shù)mayInterruptIfRunning表示是否取消正在執(zhí)行卻沒有執(zhí)行完成的任務(wù),為true時取消,false時不取消。如果任務(wù)已經(jīng)完成,則返回false。
isCancelled:
返回任務(wù)是否被成功取消,若果任務(wù)完成前被取消成功,返回true
isDone:
返回任務(wù)是否完成
get:
獲取執(zhí)行結(jié)果,阻塞一直等到任務(wù)執(zhí)行完畢
get(long timeout,TimeUnit unit):
獲取執(zhí)行結(jié)果,如果在指定時間內(nèi)沒有獲取到結(jié)果,返回null。
2.FutureTask
Future接口的唯一實現(xiàn)類
繼承關(guān)系為 FutureTask實現(xiàn)了RunnableFuture接口,RunnableFuture繼承了Runnable和Future接口。所以FutureTask即可以作為Runnable被線程執(zhí)行,也可以作為Future獲取Callable的返回值
使用范例:
FutureTask+Callable
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class ThreadTest implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println(Thread.currentThread().getName());
Thread.sleep(3000);
return Thread.currentThread().getName();
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ThreadTest threadTest = new ThreadTest();
FutureTask<String> futureTask = new FutureTask<>(threadTest);
Thread thread = new Thread(futureTask1);
thread.start();
System.out.println(futureTask.get());
}
}
Future+線程池
import java.util.concurrent.*;
public class FutureTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
Future<String> submit = executorService.submit(() -> {
System.out.println(Thread.currentThread().getName());
return "aaa";
});
System.out.println(submit.get());
}
}
三、線程池工具類Executors(阿里java代碼規(guī)范不建議使用Executors創(chuàng)建線程池,不直觀)
Executors線程池工具可以簡單的創(chuàng)建線程池,常用的為
- 固定線程數(shù)線程池newFixedThreadPool(int nThreads)
創(chuàng)建一個定長線程池,可控制線程最大并發(fā)數(shù),超出的線程會在隊列中等待。 - 工作竊取線程池(搶占式線程池)WorkStealingPool
- 單線程線程池 newSingleThreadExecutor
創(chuàng)建一個單線程化的線程池,它只會用唯一的工作線程來執(zhí)行任務(wù),保證所有任務(wù)按照指定順序(FIFO, LIFO, 優(yōu)先級)執(zhí)行。 - 帶緩存的線程池 newCachedThreadPool
彈性的線程池線程管理,用多少線程給多大的線程池,不用后及時回收,用則新建 - 任務(wù)調(diào)度線程池 newScheduledThreadPool
創(chuàng)建一個定長線程池,支持定時及周期性任務(wù)執(zhí)行。
四、ThreadPoolExecutor解析
此處踩的坑為maximumPoolSize只有在隊列已滿時才生效
參數(shù):
| 參數(shù) | 類型 | 含義 |
|---|---|---|
| corePoolSize | int | 核心線程池大小 |
| maximumPoolSize | int | 最大線程池大小 |
| keepAliveTime | long | 線程最大空閑時間 |
| unit | TimeUnit | 線程最大空閑時間的單位 |
| workQueue | BlockingQueue<Runnable> | 任務(wù)等待隊列 |
| threadFactory | ThreadFactory | 線程創(chuàng)建工廠 |
| handler | RejectedExecutionHandler | 當(dāng)線程達(dá)到最大數(shù)且任務(wù)等待隊列達(dá)到最大時的拒絕策略 |
api
void allowCoreThreadTimeOut(boolean value) 設(shè)置核心線程超時時是否回收
線程創(chuàng)建邏輯為:
- 如果當(dāng)前線程數(shù)小于核心線程數(shù),創(chuàng)建新的線程執(zhí)行任務(wù)
- 如果當(dāng)前線程數(shù)不小于核心線程數(shù),將任務(wù)放入任務(wù)等待隊列中
- 如果任務(wù)等待隊列已滿,嘗試創(chuàng)建任務(wù)線程執(zhí)行任務(wù)
- 如果創(chuàng)建任務(wù)線程失敗,根據(jù)配置的任務(wù)拒絕策略執(zhí)行操作