欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android多線程之同步鎖的使用

 更新時(shí)間:2017年08月15日 11:43:02   作者:blueberry_mu  
本篇文章主要介紹了Android多線程之同步鎖的使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

本文主要介紹了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í)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論