日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android多线程之同步锁的使用

發布時間:2023/12/18 Android 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android多线程之同步锁的使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文主要介紹了Android多線程之同步鎖的使用,分享給大家,具體如下:

一、同步機制關鍵字synchronized

對于Java來說,最常用的同步機制就是synchronized關鍵字,他是一種基于語言的粗略鎖,能夠作用于對象、函數、class。每個對象都只有一個鎖,誰能夠拿到這個鎖誰就有訪問權限。當synchronized作用于函數時,實際上鎖的也是對象,鎖定的對象就是該函數所在類的對象。而synchronized作用于class時則是鎖的這個Class類,并非具體對象。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

public class SynchronizedClass {

??public synchronized void syncMethod(){

????//代碼

??}

?

??public void syncThis(){

????synchronized (this){

??????//代碼

????}

??}

?

??public void syncClassMethod(){

????synchronized (SynchronizedClass.class){

??????//代碼

????}

??}

?

??public synchronized static void syncStaticMethod(){

????//代碼

??}

}

上面演示了同步方法、同步塊、同步class對象、同步靜態方法。前2種鎖的是對象,而后兩種鎖的是class對象。對于class對象來說,它的作用是防止多個線程同時訪問添加了synchronized鎖的代碼塊,而synchronized作用于引用對象是防止其他線程訪問同一個對象中synchronized代碼塊或者函數。

二、顯示鎖———-ReentrankLock和Condition

ReentrankLock 和內置鎖synchronized相比,實現了相同的語義,但是更具有更高的靈活性。

(1)獲得和釋放的靈活性。
(2)輪訓鎖和定時鎖。
(3)公平性。

基本操作:

lock(): 獲取鎖

tryLock(): 嘗試獲取鎖

tryLock(long timeout,TimeUnit unit): 嘗試獲取鎖,如果到了指定的時間還獲取不到,那么超時。

unlock(): 釋放鎖

newCondition(): 獲取鎖的 Condition

使用ReentrantLock的一般組合是 lock、tryLock、與unLock成對出現,需要注意的是,千萬不要忘記調用unlock來釋放鎖,負責可能引發死鎖的問題。ReentrantLock的常用形式如下所示:

?

1

2

3

4

5

6

7

8

9

10

11

12

public class ReentrantLockDemo {

??Lock lock = new ReentrantLock();

?

??public void doSth(){

????lock.lock();

????try {

??????//執行某些操作

????}finally {

??????lock.unlock();

????}

??}

}

需要注意的是,lock必須在finally開中釋放,否則,如果受保護的代碼拋出異常,鎖就可能永遠得不到釋放!!

ReentrantLock類中還有一個重要的函數newCondition(),該函數用戶獲取Lock()上的一個條件,也就是說Condition與Lock綁定。Condition用于實現線程間的通信,他是為了解決Object.wait(),nofity(),nofityAll() 難以使用的問題。
Condition的方法如下:

await() : 線程等待

await(int time,TimeUnit unit) 線程等待特定的時間,超過的時間則為超時。

signal() 隨機喚醒某個等待線程

signal() 喚醒所有等待中的線程

示例代碼:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

public class MyArrayBlockingQueue<T> {

?

//? 數據數組

??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 ;

//? 數據的個數

??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("數據已滿,等待");

????????notFull.await();

??????}

??????items[tail] =t ;

??????if(++tail ==getCapacity()){

????????tail = 0;

??????}

??????++count;

??????notEmpty.signalAll();//喚醒等待數據的線程

????} 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("還沒有數據,等待");

????????//哪個線程調用await()則阻塞哪個線程

????????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("結束");

??}

}

執行結果:

3
24
還沒有數據,等待

三、信號量 Semaphore

Semaphore是一個計數信號量,它的本質是一個“共享鎖”。信號量維護了一個信號量許可集,線程可以通過調用acquire()來獲取信號量的許可。當信號量中有可用的許可時,線程能獲取該許可;否則線程必須等待,直到可用的許可為止。線程可以通過release()來釋放它所持有的信號量許可。

示例:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

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);

????}

??}

}

以上就是本文的全部內容,希望對大家的學習有所幫助

總結

以上是生活随笔為你收集整理的Android多线程之同步锁的使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。