【并发】android中的synchronized

2024-09-03 14:58
文章标签 android 并发 synchronized

本文主要是介绍【并发】android中的synchronized,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

synchronized用于多线程访问,并且被修饰的部分不能同时被执行,是代码同步的一种方式。

1 使用synchronized修饰方法

1.1 synchronized修饰方法原理

  • 过程:当多个线程同时访问被synchronized修饰的方法是,有且仅有一个线程可以被访问,当一个线程在访问时,其它线程只能等待。当一个线程访问完毕后,下一个线程才可以访问。
  • 原理:当方法被synchronized修饰后,如果想要执行该方法就必须获得相应的锁。每个类有且仅有一个锁(针对静态方法),每个类的实例也是有且仅有一个锁。当多个线程在同时访问同一个方法时,执行该方法就必须获得相应的锁,同时锁只有一个,所以只能有一个线程可以获得锁,其它的线程必须等待该线程释放锁后才能获取到该锁。
  • 进阶说明:由于每个类只有一个锁,所以当一个类中有多个方法被synchronized修饰时,在同一时间内只能有一个方法可以获得锁,所以只有一个被synchronized修饰的方法可以执行。

1.2 synchronized修饰方法示例

    public void showDo(String msg){for(int i=0;i<1000000;i++){if (i%100000==0){System.out.println("打印结果"+msg+i/100000);}}}//使用new Thread(){@Overridepublic void run() {super.run();showDo("线程一");}}.start();new Thread(){@Overridepublic void run() {super.run();showDo("线程二");}}.start();

结果:
image.png

未加synchronized修饰方法,可以看到执行顺序是打乱的,无序的。加了synchronized后:

    public synchronized void showDo(String msg){for(int i=0;i<1000000;i++){if (i%100000==0){System.out.println("打印结果"+msg+i/100000);}}}

结果
image.png

2 使用synchronized修饰代码块

2.1使用synchronized修饰代码块说明

当使用synchronized在修饰代码块的时候需要一个自定义锁,当在多线程访问代码块的时候,只要获得自定义锁就可以执行。自定义锁可以是一个类,也可以是一个实例(可以是Object的子类,也可以是当前类自己),当具有相同自定义锁时代码块会顺序执行,当锁不同的时候互不影响。

2.2 使用synchronized修饰代码块示例

    private static String s1 = "";private static String s2 = "aa";public void showDo(String msg) {synchronized (s1){for (int i = 0; i < 1000000; i++) {if (i % 100000 == 0) {System.out.println("打印结果" + msg + i / 100000);}}}}public void showDo1(String msg) {synchronized (s2){for (int i = 0; i < 1000000; i++) {if (i % 100000 == 0) {System.out.println("打印" + msg + i / 100000);}}}}//调用new Thread() {@Overridepublic void run() {super.run();showDo1("线程一");}}.start();new Thread() {@Overridepublic void run() {super.run();showDo("线程二");showDo1("线程二");}}.start();

结果:
image.png

由上可得,多个同步锁,只有竞争同一个同步锁才会需要等待,不是竞争同一个锁的代码块互不影响。

  • synchronized不能修饰构造函数
  • 定义接口方法时不能使用synchronized
  • synchronized(this)锁的是当前对象,当前有几个对象,this就有多少份
  • synchronized(XX.class)这个与当前对象无关,只要锁是XX.class的都会被同步
  • 如果同一个类中有多个方法使用了同步锁synchronized(this)或者多个方法被synchronized修饰,则多个线程访问该类中同步方法时,每次只能访问一个,其它的被阻塞。如:
public synchronized void A(){......
}
public synchronized void B(){......
}

有两个线程分别访问同一个对象T的A方法和B方法,则同时只能有一个方法被其中一个线程访问,另一个线程处于阻塞状态,因为方法A和B持有同一个对象锁,synchronized(this)也是类似的情况。

  • 同一个类中有多个方法使用了同步锁synchronized修饰,且这些类是静态的,因为静态方法是属于类的,而不是属于某个对象的,所以它与synchronized(XX.class)类似。
public synchronized static void method() {// todo
}
  • 每个对象只有一个锁(lock)与之相关联,谁拿到这个锁谁就可以运行它所控制的那段代码。
  • 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。

这篇关于【并发】android中的synchronized的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1133282

相关文章

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

高并发环境中保持幂等性

在高并发环境中保持幂等性是一项重要的挑战。幂等性指的是无论操作执行多少次,其效果都是相同的。确保操作的幂等性可以避免重复执行带来的副作用。以下是一些保持幂等性的常用方法: 唯一标识符: 请求唯一标识:在每次请求中引入唯一标识符(如 UUID 或者生成的唯一 ID),在处理请求时,系统可以检查这个标识符是否已经处理过,如果是,则忽略重复请求。幂等键(Idempotency Key):客户端在每次

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR

Java并发编程之——BlockingQueue(队列)

一、什么是BlockingQueue BlockingQueue即阻塞队列,从阻塞这个词可以看出,在某些情况下对阻塞队列的访问可能会造成阻塞。被阻塞的情况主要有如下两种: 1. 当队列满了的时候进行入队列操作2. 当队列空了的时候进行出队列操作123 因此,当一个线程试图对一个已经满了的队列进行入队列操作时,它将会被阻塞,除非有另一个线程做了出队列操作;同样,当一个线程试图对一个空