国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android多線程之同步鎖的使用

2019-12-12 02:15:09
字體:
來源:轉載
供稿:網友

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

一、同步機制關鍵字synchronized

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

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的常用形式如下所示:

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() 喚醒所有等待中的線程

示例代碼:

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()來釋放它所持有的信號量許可。

示例:

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 洪江市| 留坝县| 井研县| 密山市| 永清县| 高淳县| 孝昌县| 永川市| 霍山县| 古蔺县| 张家界市| 东源县| 合作市| 始兴县| 和田市| 孝感市| 电白县| 托克逊县| 大石桥市| 广宗县| 酒泉市| 工布江达县| 萍乡市| 剑阁县| 丽水市| 西城区| 水富县| 无为县| 汉川市| 萨嘎县| 江都市| 永丰县| 堆龙德庆县| 江山市| 祥云县| 金堂县| 长治县| 长寿区| 洛川县| 盐城市| 广宁县|