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