中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android中怎么利用同步鎖實現多線程

發布時間:2021-06-26 17:00:22 來源:億速云 閱讀:161 作者:Leah 欄目:移動開發

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

看完上述內容,你們掌握Android中怎么利用同步鎖實現多線程的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

达日县| 九台市| 敦化市| 乐清市| 丰城市| 宁化县| 邳州市| 克东县| 西昌市| 德安县| 黄骅市| 茂名市| 繁峙县| 南乐县| 阿克| 兰溪市| 平安县| 西峡县| 东城区| 商水县| 张掖市| 正镶白旗| 京山县| 永善县| 永德县| 仁怀市| 旬邑县| 同德县| 泽库县| 高要市| 郧西县| 岢岚县| 澜沧| 仁布县| 舞钢市| 渑池县| 苏尼特右旗| 景谷| 胶州市| 贺兰县| 天祝|