摘要:的多任務執(zhí)行框架提供了一套線程框架來幫助開發(fā)者有效的進行線程控制,扮演線程工廠的角色,其創(chuàng)建線程的方法如下返回固定數(shù)量的線程池,該方法的線程數(shù)始終不變。
1.Jdk的多任務執(zhí)行框架
JDK提供了一套線程框架Executor來幫助開發(fā)者有效的進行線程控制,Executors扮演線程工廠的角色,其創(chuàng)建線程的方法如下
newFixedThreadPool() 返回固定數(shù)量的線程池,該方法的線程數(shù)始終不變。若線程空閑則立即執(zhí)行 否則暫緩到隊列中
newSingleThreadPool() 創(chuàng)建一個線程池,若線程空閑則立即執(zhí)行 否則暫緩到隊列中
newCachedThreadPool() 返回一個可根據(jù)實際情況調(diào)整線程個數(shù)的線程池 ,若線程空閑則立即執(zhí)行 否則暫緩到隊列中
newScheduledThreadPool() 返回一個ScheduledExecutorService對象,但該線程可以執(zhí)行線程的數(shù)量(schedule 排定/安排/目錄)
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(10); //command 就是一個Thread ScheduledFuture> scheduledTask = scheduler.scheduleWithFixedDelay(command,5,1, TimeUnit.SECONDS);
若Executors工廠類無法滿足我們的需求,可以自己去創(chuàng)建自定義的線程池。自定義線程池的構造方法如下
public ThreadPoolExecutor(int corePoolSize,//核心線程數(shù) int maximumPoolSize,//最大線程數(shù) long keepAliveTime,//線程的空閑時間 TimeUnit unit,//給定單元粒度的時間段 BlockingQueueworkQueue,//有界、無界隊列 RejectedExecutoionHandler handler//任務拒絕策略 ){.....}
使用什么隊列對該構造方法來說比較關鍵
使用有界隊列 如有任務需要執(zhí)行 如果實際線程數(shù) 使用無界隊列LinkedBlockingQueue 除非系統(tǒng)資源耗盡 否則不會出現(xiàn)入隊失敗 JDK的拒絕策略 AbortPolicy:直接拋出異常 系統(tǒng)正常工作 CallerRunsPolicy:只要線程池未被關閉 嘗試運行被丟棄的任務 DiscardOldestPolicy:丟失最老的請求 嘗試提交當前任務 DiscardPolicy:丟棄無法處理的任務不給予處理 JDK提供的拒絕策略不友好,可以自定義拒絕策略,實現(xiàn)RejectedExecutionHandler接口(添加日志等等) 2.Concurrent.util工具類詳解 CyclicBarrier CountDownLatch Callable 和Future使用 Semaphore信號量 3.鎖的高級深化 Lock and Condition 使用Lock對象也可以實現(xiàn)同步互斥 如果多個線程之間需要實現(xiàn)協(xié)作 使用Object的wait和nofity,notifyAll 在使用Lock的時候可以使用一個新的等待/通知的類Condition 只針對一個具體的鎖 ReentrantLock重入鎖 ReentrantReadWriteLock讀寫鎖 鎖的優(yōu)化 避免死鎖 減少鎖的持有時間 減少鎖的粒度 鎖的分離 盡量使用無鎖的操作 比如原子類操作 如果實際線程數(shù)>corePoolSize,則將任務添加到緩存隊列
如果緩存隊列已滿 ,總線程
如有任務需要執(zhí)行 如果實際線程數(shù)
BlockingQueue
public class MyRejected implements RejectedExecutionHandler {
public MyRejected(){}
@Override
public void rejectedExecution(Runnable r,
ThreadPoolExecutor executor) {
System.out.println("自定義處理");
System.out.println("當前被拒絕的任務為"+r.toString());
}
}
假設每一個線程代表一個運動員,當運動員都準備好了,才能一起出發(fā)。CyclicBarrier barrier = new CyclicBarrier(3);
經(jīng)常用于監(jiān)聽某些初始化操作,當初始化執(zhí)行完畢以后,通知主線程繼續(xù)工作final CountDownLatch countDownLatch = new CountDownLatch(2);
Futrue模式費用適合在處理耗時很長的業(yè)務邏輯進行使用,可以有效的減小系統(tǒng)的影響,
提高系統(tǒng)的吞吐量 public class UseFuture implements Callable
可以控制系統(tǒng)的流量,拿到線程的信號量則訪問否則等待
通過acquire和release來獲取和釋放線程 final Semaphore semp = new Semaphore(5);
使用synchronized關鍵字可以實現(xiàn)線程間的同步互斥工作 public class UseCondition {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void method1(){
try {
lock.lock();
System.out.println("當前線程:" +
Thread.currentThread().getName() + "進入等待狀態(tài)..");
Thread.sleep(3000);
System.out.println("當前線程:" +
Thread.currentThread().getName() + "釋放鎖..");
condition.await(); // Object wait
System.out.println("當前線程:" +
Thread.currentThread().getName() +"繼續(xù)執(zhí)行...");
condition.signal(); //Object notify
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
private Lock lock = new ReentrantLock(boolean isFair);//是否為公平鎖
核心是實現(xiàn)讀寫分離 在都多寫少的情況下 性能高于重入鎖public class UseReentrantReadWriteLock {
private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
private ReadLock readLock = rwLock.readLock();
private WriteLock writeLock = rwLock.writeLock();
public void read(){
try {
readLock.lock();
System.out.println("當前線程:" +
Thread.currentThread().getName() + "進入...");
Thread.sleep(3000);
System.out.println("當前線程:" +
Thread.currentThread().getName() + "退出...");
} catch (Exception e) {
e.printStackTrace();
} finally {
readLock.unlock();
}
}
public void write(){
try {
writeLock.lock();
System.out.println("當前線程:" +
Thread.currentThread().getName() + "進入...");
Thread.sleep(3000);
System.out.println("當前線程:" +
Thread.currentThread().getName() + "退出...");
} catch (Exception e) {
e.printStackTrace();
} finally {
writeLock.unlock();
}
}
}
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/70552.html
摘要:今天給大家總結一下,面試中出鏡率很高的幾個多線程面試題,希望對大家學習和面試都能有所幫助。指令重排在單線程環(huán)境下不會出先問題,但是在多線程環(huán)境下會導致一個線程獲得還沒有初始化的實例。使用可以禁止的指令重排,保證在多線程環(huán)境下也能正常運行。 下面最近發(fā)的一些并發(fā)編程的文章匯總,通過閱讀這些文章大家再看大廠面試中的并發(fā)編程問題就沒有那么頭疼了。今天給大家總結一下,面試中出鏡率很高的幾個多線...
摘要:對象改變條件對象當前線程要等待線程終止之后才能從返回。如果線程在上的操作中被中斷,通道會被關閉,線程的中斷狀態(tài)會被設置,并得到一個。清除線程的中斷狀態(tài)。非公平性鎖雖然可能造成饑餓,但極少的線程切換,保證其更大的吞吐量。 聲明:Java并發(fā)的內(nèi)容是自己閱讀《Java并發(fā)編程實戰(zhàn)》和《Java并發(fā)編程的藝術》整理來的。 showImg(https://segmentfault.com/im...
摘要:如問到是否使用某框架,實際是是問該框架的使用場景,有什么特點,和同類可框架對比一系列的問題。這兩個方向的區(qū)分點在于工作方向的側重點不同。 [TOC] 這是一份來自嗶哩嗶哩的Java面試Java面試 32個核心必考點完全解析(完) 課程預習 1.1 課程內(nèi)容分為三個模塊 基礎模塊: 技術崗位與面試 計算機基礎 JVM原理 多線程 設計模式 數(shù)據(jù)結構與算法 應用模塊: 常用工具集 ...
閱讀 1002·2021-11-24 10:30
閱讀 2326·2021-10-08 10:04
閱讀 3967·2021-09-30 09:47
閱讀 1452·2021-09-29 09:45
閱讀 1445·2021-09-24 10:33
閱讀 6271·2021-09-22 15:57
閱讀 2357·2021-09-22 15:50
閱讀 4088·2021-08-30 09:45