| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> Android synchronized -> 正文阅读 |
|
[移动开发]Android synchronized |
1.synchronized synchronized用于多线程访问,并且被修饰的部分不能同时被执行,是代码同步的一种方式。 ①使用synchronized修饰方法 当多个线程同时访问被synchronized修饰的方法时,有且仅有一个线程可以被访问,当一个线程在访问时,其它线程只能等待。当一个线程访问完毕后,下一个线程才可以访问。 原理:当方法被synchronized修饰后,如果想要执行该方法就必须获得相应的锁。每个类有且仅有一个锁(针对静态方法),每个类的实例也是有且仅有一个锁。当多个线程在同时访问同一个方法时,执行该方法就必须获得相应的锁,同时锁只有一个,所以只能有一个线程可以获得锁,其它的线程必须等待该线程释放锁后才能获取到该锁。 进阶说明:由于每个类只有一个锁,所以当一个类中有多个方法被synchronized修饰时,在同一时间内只能有一个方法可以获得锁,所以只有一个被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(){ ? ? @Override ? ? public void run() { ? ? ? ? super.run(); ? ? ? ? showDo("线程一"); ? ? } }.start(); new Thread(){ ? ? @Override ? ? public void run() { ? ? ? ? super.run(); ? ? ? ?showDo("线程二"); ? ? } }.start(); 未加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); ? ? ? ? } ? ? } } 这也就是同步方法,这时synchronized锁定的是哪个对象呢?他锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中执行这个同步方法时,他们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却能够任意调用这个被加了synchronized关键字的方法。 上边的示例代码等同于如下代码: public void method()? {? ? ?? ? ? synchronized (this) {? ? ?? ? ? ? ?//…..? ? ?? ? ? }? ? ?? }? ? ? this指的是什么呢?他指的就是调用这个方法的对象,如P1。可见同步方法实质是将synchronized作用于object reference。――那个拿到了P1对象锁的线程,才能够调用P1的同步方法,而对P2而言,P1这个锁和他毫不相干,程序也可能在这种情形下摆脱同步机制的控制,造成数据混乱。 ②使用synchronized修饰代码块 public void method(SomeObject so) {? ? ?? ? ? synchronized(so)? {? ? ?? ? ? ? ?//…..? ? ?? ? ? }? ? ?? }? ? ? 这时,锁就是so这个对象,谁拿到这个锁谁就能够运行他所控制的那段代码。当有一个明确的对象作为锁时,就能够这样写,但当没有明确的对象作为锁,只是想让一段代码同步时,能够创建一个特别的instance变量(得是个对象)来充当锁: class Foo implements Runnable?{? ? ?? ? ?private byte[] lock = new byte[0]; // 特别的instance变量? ? ?? ??Public void method()?{? ? ?? ? ? ? ?synchronized(lock) { //… }? ? ?? ? }? ? ?? ? //…..? ? ?? } 注:零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码。 ?举例说明: private static String s1 = ""; private static String s2 = "aa"; public void showDo(String msg) { ? ? synchronized (s1){ ? ? ? ? for (int i = 0; i < 10; i++) { ? ? ? ? ? ? if (i % 2?== 0) { ? ? ? ? ? ? ? ? System.out.println("打印结果" + msg + i / 2); ? ? ? ? ? ? } ? ? ? ? } ? ? } } public void showDo1(String msg) { ? ? synchronized (s2){ ? ? ? ? for (int i = 0; i < 10; i++) { ? ? ? ? ? ? if (i % 12?== 0) { ? ? ? ? ? ? ? ? System.out.println("打印" + msg + i / 2); ? ? ? ? ? ? } ? ? ? ? } ? ? } } //调用 new Thread() { ? ? @Override ? ? public void run() { ? ? ? ? super.run(); ? ? ? ? showDo1("线程一"); ? ?} }.start(); new Thread() { ? ? @Override ? ? public void run() { ? ? ? ? super.run(); ? ? ? ? showDo("线程二"); ? ? ? ? showDo1("线程二"); ? ? } }.start(); 由上可得,多个同步锁,只有竞争同一个同步锁才会需要等待,不是竞争同一个锁的代码块互不影响。 ③ 2. 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)与之相关联,谁拿到这个锁谁就可以运行它所控制的那段代码。 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。 ? 更有一些技巧能够让我们对共享资源的同步访问更加安全:? ? |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 18:53:59- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |