Android多線程之同步鎖的使用
本文主要介紹了Android多線程之同步鎖的使用,分享給大家,具體如下:
一、同步機(jī)制關(guān)鍵字synchronized
對(duì)于Java來(lái)說(shuō),最常用的同步機(jī)制就是synchronized關(guān)鍵字,他是一種基于語(yǔ)言的粗略鎖,能夠作用于對(duì)象、函數(shù)、class。每個(gè)對(duì)象都只有一個(gè)鎖,誰(shuí)能夠拿到這個(gè)鎖誰(shuí)就有訪問(wèn)權(quán)限。當(dāng)synchronized作用于函數(shù)時(shí),實(shí)際上鎖的也是對(duì)象,鎖定的對(duì)象就是該函數(shù)所在類的對(duì)象。而synchronized作用于class時(shí)則是鎖的這個(gè)Class類,并非具體對(duì)象。
public class SynchronizedClass { public synchronized void syncMethod(){ //代碼 } public void syncThis(){ synchronized (this){ //代碼 } } public void syncClassMethod(){ synchronized (SynchronizedClass.class){ //代碼 } } public synchronized static void syncStaticMethod(){ //代碼 } }
上面演示了同步方法、同步塊、同步class對(duì)象、同步靜態(tài)方法。前2種鎖的是對(duì)象,而后兩種鎖的是class對(duì)象。對(duì)于class對(duì)象來(lái)說(shuō),它的作用是防止多個(gè)線程同時(shí)訪問(wèn)添加了synchronized鎖的代碼塊,而synchronized作用于引用對(duì)象是防止其他線程訪問(wèn)同一個(gè)對(duì)象中synchronized代碼塊或者函數(shù)。
二、顯示鎖———-ReentrankLock和Condition
ReentrankLock 和內(nèi)置鎖synchronized相比,實(shí)現(xiàn)了相同的語(yǔ)義,但是更具有更高的靈活性。
(1)獲得和釋放的靈活性。
(2)輪訓(xùn)鎖和定時(shí)鎖。
(3)公平性。
基本操作:
lock(): 獲取鎖
tryLock(): 嘗試獲取鎖
tryLock(long timeout,TimeUnit unit): 嘗試獲取鎖,如果到了指定的時(shí)間還獲取不到,那么超時(shí)。
unlock(): 釋放鎖
newCondition(): 獲取鎖的 Condition
使用ReentrantLock的一般組合是 lock、tryLock、與unLock成對(duì)出現(xiàn),需要注意的是,千萬(wàn)不要忘記調(diào)用unlock來(lái)釋放鎖,負(fù)責(zé)可能引發(fā)死鎖的問(wèn)題。ReentrantLock的常用形式如下所示:
public class ReentrantLockDemo { Lock lock = new ReentrantLock(); public void doSth(){ lock.lock(); try { //執(zhí)行某些操作 }finally { lock.unlock(); } } }
需要注意的是,lock必須在finally開(kāi)中釋放,否則,如果受保護(hù)的代碼拋出異常,鎖就可能永遠(yuǎn)得不到釋放??!
ReentrantLock類中還有一個(gè)重要的函數(shù)newCondition(),該函數(shù)用戶獲取Lock()上的一個(gè)條件,也就是說(shuō)Condition與Lock綁定。Condition用于實(shí)現(xiàn)線程間的通信,他是為了解決Object.wait(),nofity(),nofityAll() 難以使用的問(wèn)題。
Condition的方法如下:
await() : 線程等待
await(int time,TimeUnit unit) 線程等待特定的時(shí)間,超過(guò)的時(shí)間則為超時(shí)。
signal() 隨機(jī)喚醒某個(gè)等待線程
signal() 喚醒所有等待中的線程
示例代碼:
public class MyArrayBlockingQueue<T> { // 數(shù)據(jù)數(shù)組 private final T[] items; private final Lock lock = new ReentrantLock(); private Condition notFull = lock.newCondition(); private Condition notEmpty = lock.newCondition() ; // 頭部索引 private int head; // 尾部索引 private int tail ; // 數(shù)據(jù)的個(gè)數(shù) private int count; public MyArrayBlockingQueue(int maxSize) { items = (T[]) new Object[maxSize]; } public MyArrayBlockingQueue(){ this(10); } public void put(T t){ lock.lock(); try { while(count == getCapacity()){ System.out.println("數(shù)據(jù)已滿,等待"); notFull.await(); } items[tail] =t ; if(++tail ==getCapacity()){ tail = 0; } ++count; notEmpty.signalAll();//喚醒等待數(shù)據(jù)的線程 } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } } public int getCapacity(){ return items.length ; } public T take(){ lock.lock(); try { while(count ==0){ System.out.println("還沒(méi)有數(shù)據(jù),等待"); //哪個(gè)線程調(diào)用await()則阻塞哪個(gè)線程 notEmpty.await(); } T ret = items[head]; items[head] = null ; if(++head == getCapacity()){ head =0 ; } --count; notFull.signalAll(); return ret ; } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } return null ; } public int size(){ lock.lock(); try { return count; }finally { lock.unlock(); } } public static void main(String[] args){ MyArrayBlockingQueue<Integer> aQueue = new MyArrayBlockingQueue<>(); aQueue.put(3); aQueue.put(24); for(int i=0;i<5;i++){ System.out.println(aQueue.take()); } System.out.println("結(jié)束"); } }
執(zhí)行結(jié)果:
3
24
還沒(méi)有數(shù)據(jù),等待
三、信號(hào)量 Semaphore
Semaphore是一個(gè)計(jì)數(shù)信號(hào)量,它的本質(zhì)是一個(gè)“共享鎖”。信號(hào)量維護(hù)了一個(gè)信號(hào)量許可集,線程可以通過(guò)調(diào)用acquire()來(lái)獲取信號(hào)量的許可。當(dāng)信號(hào)量中有可用的許可時(shí),線程能獲取該許可;否則線程必須等待,直到可用的許可為止。線程可以通過(guò)release()來(lái)釋放它所持有的信號(hào)量許可。
示例:
public class SemaphoreTest { public static void main(String[] args){ final ExecutorService executorService = Executors.newFixedThreadPool(3); final Semaphore semaphore = new Semaphore(3); List<Future> futures = new ArrayList<>(); for (int i = 0; i < 5; i++) { Future<?> submit = executorService.submit(new Runnable() { @Override public void run() { try { semaphore.acquire(); System.out.println(" 剩余許可: " + semaphore.availablePermits()); Thread.sleep(3000); semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } } }); futures.add(submit); } } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android異步方法以同步方式實(shí)現(xiàn)
- Android seekbar(自定義)控制音量同步更新
- android-獲取網(wǎng)絡(luò)時(shí)間、獲取特定時(shí)區(qū)時(shí)間、時(shí)間同步的方法
- android中ListView數(shù)據(jù)刷新時(shí)的同步方法
- Android實(shí)現(xiàn)歌曲播放時(shí)歌詞同步顯示具體思路
- Android獲取點(diǎn)擊屏幕的位置坐標(biāo)
- Android 5.0+ 屏幕錄制實(shí)現(xiàn)的示例代碼
- Android自適應(yīng)不同屏幕大小的全部方法
- Android6.0開(kāi)發(fā)中屏幕旋轉(zhuǎn)原理與流程分析
- Android手機(jī)屏幕同步工具asm.jar
相關(guān)文章
Android實(shí)現(xiàn)獲取SERIAL信息的方法
這篇文章主要介紹了Android實(shí)現(xiàn)獲取SERIAL信息的方法,涉及Android操作SERIAL的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10Android設(shè)置Padding和Margin(動(dòng)態(tài)/靜態(tài))的方法實(shí)例
如何在java代碼中設(shè)置margin,也就是組件與組件之間的間距,下面這篇文章主要給大家介紹了關(guān)于Android設(shè)置Padding和Margin(動(dòng)態(tài)/靜態(tài))的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11Android如何實(shí)現(xiàn)壓縮和解壓縮文件
這篇文章主要介紹了Android實(shí)現(xiàn)壓縮和解壓文件的實(shí)例代碼,涉及到批量壓縮文件夾,解壓縮一個(gè)文件等方面的知識(shí)點(diǎn),本文介紹的非常詳細(xì),具有參考借鑒價(jià)值,感興趣的朋友一起看下吧2016-05-05鴻蒙開(kāi)源第三方組件之連續(xù)滾動(dòng)圖像組件功能
這篇文章主要介紹了鴻蒙開(kāi)源第三方組件之連續(xù)滾動(dòng)圖像組件功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04Android中使用AsyncTask做下載進(jìn)度條實(shí)例代碼
這篇文章主要介紹了Android中使用AsyncTask做下載進(jìn)度條實(shí)例代碼的相關(guān)資料,這里附有實(shí)例代碼,具有一定參考價(jià)值,需要的朋友可以參考下2017-01-01Android 判斷SIM卡屬于哪個(gè)移動(dòng)運(yùn)營(yíng)商詳解及實(shí)例
這篇文章主要介紹了Android 判斷SIM卡屬于哪個(gè)移動(dòng)運(yùn)營(yíng)商詳解相關(guān)資料,并附實(shí)例代碼,具有一定參考價(jià)值,需要的朋友可以參考下2016-11-11Android利用Senser實(shí)現(xiàn)不同的傳感器
這篇文章主要為大家詳細(xì)介紹了Android利用Senser實(shí)現(xiàn)不同傳感器的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02Android開(kāi)發(fā)返回鍵明暗點(diǎn)擊效果的實(shí)例代碼
這篇文章主要介紹了Android開(kāi)發(fā)返回鍵明暗點(diǎn)擊效果的實(shí)例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04Android使用TabLayou+fragment+viewpager實(shí)現(xiàn)滑動(dòng)切換頁(yè)面效果
這篇文章主要介紹了Android使用TabLayou+fragment+viewpager實(shí)現(xiàn)滑動(dòng)切換頁(yè)面效果,需要的朋友可以參考下2017-05-05