全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Android多线程之同步锁的使用

本文主要介绍了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多线程同步锁  # Android  # 同步锁  # Android异步方法以同步方式实现  # Android seekbar(自定义)控制音量同步更新  # android-获取网络时间、获取特定时区时间、时间同步的方法  # android中ListView数据刷新时的同步方法  # Android实现歌曲播放时歌词同步显示具体思路  # Android获取点击屏幕的位置坐标  # Android 5.0+ 屏幕录制实现的示例代码  # Android自适应不同屏幕大小的全部方法  # Android6.0开发中屏幕旋转原理与流程分析  # Android手机屏幕同步工具asm.jar  # 信号量  # 的是  # 作用于  # 是一个  # 他是  # 可以通过  # 死锁  # 需要注意  # 多个  # 两种  # 中有  # 更高  # 给大家  # 还有一个  # 谁能  # 所示  # 所持  # 都只  # 则为  # 绑定 


相关文章: 宝塔建站教程:一键部署配置流程与SEO优化实战指南  北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?  定制建站平台哪家好?企业官网搭建与快速建站方案推荐  建站之星ASP如何实现CMS高效搭建与安全管理?  建站主机选哪家性价比最高?  免费网站制作模板下载,除了易企秀之外还有什么H5平台可以制作H5长页面,最好是免费的?  已有域名和空间,如何快速搭建网站?  制作网站的过程怎么写,用凡科建站如何制作自己的网站?  宝盒自助建站智能生成技巧:SEO优化与关键词设置指南  seo网站制作优化,网站SEO优化步骤有哪些?  建站之星手机一键生成:多端自适应+小程序开发快速建站指南  网站图片在线制作软件,怎么在图片上做链接?  如何快速搭建高效可靠的建站解决方案?  创业网站制作流程,创业网站可靠吗?  如何彻底删除建站之星生成的Banner?  建站VPS推荐:2025年高性能服务器配置指南  小捣蛋自助建站系统:数据分析与安全设置双核驱动网站优化  如何高效完成独享虚拟主机建站?  广州顶尖建站服务:企业官网建设与SEO优化一体化方案  网页制作模板网站推荐,网页设计海报之类的素材哪里好?  成都品牌网站制作公司,成都营业执照年报网上怎么办理?  小型网站制作HTML,*游戏网站怎么搭建?  建站主机类型有哪些?如何正确选型  如何通过万网虚拟主机快速搭建网站?  ,柠檬视频怎样兑换vip?  网页设计网站制作软件,microsoft office哪个可以创建网页?  如何使用Golang安装API文档生成工具_快速生成接口文档  建站之星如何修改网站生成路径?  网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?  深圳网站制作培训,深圳哪些招聘网站比较好?  如何选择适合PHP云建站的开源框架?  如何通过虚拟机搭建网站?详细步骤解析  定制建站模板如何实现SEO优化与智能系统配置?18字教程  天河区网站制作公司,广州天河区如何办理身份证?需要什么资料有预约的网站吗?  如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?  上海网站制作网页,上海本地的生活网站有哪些?最好包括生活的各个方面的?  c# 在ASP.NET Core中管理和取消后台任务  网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  网站制作免费,什么网站能看正片电影?  如何通过VPS搭建网站快速盈利?  教学网站制作软件,学习*后期制作的网站有哪些?  建站之星如何取消后台验证码生成?  Avalonia如何实现跨窗口通信 Avalonia窗口间数据传递  如何制作一个表白网站视频,关于勇敢表白的小标题?  如何通过wdcp面板快速创建网站?  如何高效利用亚马逊云主机搭建企业网站?  建站主机空间推荐 高性价比配置与快速部署方案解析  PHP正则匹配日期和时间(时间戳转换)的实例代码  导航网站建站方案与优化指南:一站式高效搭建技巧解析  宝塔新建站点报错如何解决? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。