1.什么是線程涉馅,多線程
線程 : 是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位雹顺;它被包含在進(jìn)程之中斑匪,是進(jìn)程中的實(shí)際運(yùn)作單位。
多線程 : 是指從軟件或者硬件上實(shí)現(xiàn)多個(gè)線程并發(fā)執(zhí)行的技術(shù)河爹。具有多線程能力的計(jì)算機(jī)因有硬件支持而能夠在同一時(shí)間執(zhí)行多于一個(gè)線程,進(jìn)而提升整體處理性能桐款。
簡單來說:線程是程序中一個(gè)單一的順序控制流程咸这;而多線程就是在單個(gè)程序中同時(shí)運(yùn)行多個(gè)線程來完成不同的工作。
多線程的作用:是為了同步完成多項(xiàng)任務(wù)鲁僚,不是為了提高運(yùn)行效率炊苫,而是為了提高資源使用效率來提高系統(tǒng)的效率。多線程是在同一時(shí)間需要完成多項(xiàng)任務(wù)的時(shí)候?qū)崿F(xiàn)的冰沙。
2.多線程的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
1)侨艾、多線程技術(shù)可以加快程序的運(yùn)行速度,使程序的響應(yīng)速度更快拓挥,因?yàn)橛脩艚缑婵梢栽谶M(jìn)行其它工作的同時(shí)一直處于活動(dòng)狀態(tài)
2)唠梨、可以把占據(jù)長時(shí)間的程序中的任務(wù)放到后臺(tái)去處理,同時(shí)執(zhí)行其他操作侥啤,提高效率
3)当叭、當(dāng)前沒有進(jìn)行處理的任務(wù)時(shí)可以將處理器時(shí)間讓給其它任務(wù)
4)茬故、可以讓同一個(gè)程序的不同部分并發(fā)執(zhí)行,釋放一些珍貴的資源如內(nèi)存占用等等
5)蚁鳖、可以隨時(shí)停止任務(wù)
6)磺芭、可以分別設(shè)置各個(gè)任務(wù)的優(yōu)先級(jí)以優(yōu)化性能
缺點(diǎn):
1)、因?yàn)槎嗑€程需要開辟內(nèi)存醉箕,而且線程切換需要時(shí)間因此會(huì)很消耗系統(tǒng)內(nèi)存钾腺。
2)、線程的終止會(huì)對(duì)程序產(chǎn)生影響
3)讥裤、由于多個(gè)線程之間存在共享數(shù)據(jù)放棒,因此容易出現(xiàn)線程死鎖的情況
4)、對(duì)線程進(jìn)行管理要求額外的 CPU開銷己英。線程的使用會(huì)給系統(tǒng)帶來上下文切換的額外負(fù)擔(dān)间螟。
3.多線程的實(shí)現(xiàn)方式有哪些
1. 繼承Thread類,重寫run方法
2.實(shí)現(xiàn)Runnable接口损肛,重寫run方法厢破,實(shí)現(xiàn)Runnable接口的實(shí)現(xiàn)類的實(shí)例對(duì)象作為Thread構(gòu)造函數(shù)的target(無返回值)
3.實(shí)現(xiàn)Callable接口,通過Callable和FutureTask創(chuàng)建線程 (有返回值)
4.線程池:提供了一個(gè)線程隊(duì)列荧关,隊(duì)列中保存著所有等待狀態(tài)的線程溉奕。避免了創(chuàng)建與銷毀額外開銷,提高了響應(yīng)的速度忍啤。
5.CompletableFuture加勤,JDK1.8中的CompletableFuture為我們提供了異步函數(shù)式編程,CompletableFuture提供了非常強(qiáng)大的Future的擴(kuò)展功能,可以幫助我們簡化異步編程的復(fù)雜性同波,提供了函數(shù)式編程的能力鳄梅,可以通過回調(diào)的方式處理計(jì)算結(jié)果,并且提供了轉(zhuǎn)換和組合CompletableFuture的方法未檩。
6.Spring的@Async注解
4.體系結(jié)構(gòu)
java.util.concurrent.Executor : 負(fù)責(zé)線程的使用與調(diào)度的根接口
|--ExecutorService 子接口: 線程池的主要接口
|--ThreadPoolExecutor 線程池的實(shí)現(xiàn)類
|--ScheduledExecutorService 子接口:負(fù)責(zé)線程的調(diào)度
|--ScheduledThreadPoolExecutor :繼承 ThreadPoolExecutor戴尸, 實(shí)現(xiàn) ScheduledExecutorService *
工具類 : Executors
ExecutorService newFixedThreadPool() : 創(chuàng)建固定大小的線程池
ExecutorService newCachedThreadPool() : 緩存線程池,線程池的數(shù)量不固定冤狡,可以根據(jù)需求自動(dòng)的更改數(shù)量孙蒙。
ExecutorService newSingleThreadExecutor() : 創(chuàng)建單個(gè)線程池。線程池中只有一個(gè)線程
ScheduledExecutorService newScheduledThreadPool() : 創(chuàng)建固定大小的線程悲雳,可以延遲或定時(shí)的執(zhí)行任務(wù)挎峦。
5.代碼示例
public class TestThread {
public static void main(String[]args)throws Exception {
//1.繼承Thread類
? ? ? ? ThreadTest threadTest =new ThreadTest();
? ? ? ? threadTest.start();
? ? ? ? //2.實(shí)現(xiàn)Runnable接口
? ? ? ? RunnableTest runnableTest =new RunnableTest();
? ? ? ? new Thread(runnableTest).start();
? ? ? ? //3.實(shí)現(xiàn)Callable接口
? ? ? ? CallableTest callableTest =new CallableTest();
? ? ? ? FutureTask futureTask =new FutureTask<>(callableTest);
? ? ? ? new Thread(futureTask).start();
? ? ? ? Listlists = (List)futureTask.get();
? ? ? ? for (Integer integer :lists) {
System.out.print(integer +"? ");
? ? ? ? }
System.out.print("? ");
? ? ? ? //4.使用線程池
? ? ? ? ThreadPoolTest();
? ? ? ? //5.使用CompletableFuture
? ? ? ? CompletableFutureTest_runAsync();
? ? ? ? CompletableFutureTest_supplyAsync();
? ? }
static class? ThreadTest extends Thread{
@Override
? ? ? ? public void run() {
for(int i? =0 ; i <10 ; i ++) {
if(i %2 ==0) {
System.out.print(i+"? ");
? ? ? ? ? ? ? ? }
}
System.out.println(" ");
? ? ? ? }
}
static class RunnableTest implements Runnable{
@Override
? ? ? ? public void run() {
for(int i? =0 ; i <10 ; i ++) {
if(i %3 ==0) {
System.out.print(i+"? ");
? ? ? ? ? ? ? ? }
}
System.out.println(" ");
? ? ? ? }
}
static? class CallableTest implements Callable> {
@Override
? ? ? ? public Listcall()throws Exception {
Listlists =new ArrayList<>();
? ? ? ? ? ? for(int i? =3 ; i <100 ; i ++) {
if(i %4 ==0) {
lists.add(i);
? ? ? ? ? ? ? ? }
}
return lists;
? ? ? ? }
}
public static void ThreadPoolTest()throws ExecutionException, InterruptedException {
ExecutorService executorService =Executors.newFixedThreadPool(5);
? ? ? ? List>>ints =new ArrayList<>();
? ? ? ? int[]arr = {10,20,31,40,50};
? ? ? ? for(int i =0; i
int finalI =i;
? ? ? ? ? ? Future>future =executorService.submit(() -> {
System.out.println(Thread.currentThread().getName()+"? ");
? ? ? ? ? ? ? ? Listlists =new ArrayList<>();
? ? ? ? ? ? ? ? ? ? if(arr[finalI] %10 ==0) {
lists.add(arr[finalI]);
? ? ? ? ? ? ? ? ? ? }
return lists;
? ? ? ? ? ? });
? ? ? ? ? ? ints.add(future);
? ? ? ? }
for (Future>future :ints) {
System.out.println(future.get());
? ? ? ? }
}
//無返回值
? ? public static void CompletableFutureTest_runAsync()throws Exception {
CompletableFuturefuture =CompletableFuture.runAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
? ? ? ? ? ? }catch (InterruptedException e) {
}
System.out.println("run end ...");
? ? ? ? });
? ? ? ? future.get();
? ? }
//有返回值
? ? public static void CompletableFutureTest_supplyAsync()throws Exception {
CompletableFuturefuture =CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
? ? ? ? ? ? }catch (InterruptedException e) {
}
System.out.println("run end ...");
? ? ? ? ? ? return System.currentTimeMillis();
? ? ? ? });
? ? ? ? long time =future.get();
? ? ? ? System.out.println("time = "+time);
? ? }
}