AndroidDev 板


LINE

有图网志有排版好读版 http://goo.gl/cA6kBE ------ 前言 我们都知道 Android 常会利用 multi-thread 来做多工的处理 但是如果同时有两个以上的 Thread 对同一个物件做资料的存取甚至是更改 没有处理好的话会导致意想不到的结果发生. 举个例子来说,假设有一个地方邮局的邮箱如下图所示 这个邮局有两个邮差 A 跟 B 来负责送信 并且有一个人会负责记录剩余的邮件数量 我们先假设这个记录的人叫做 Kenji 好了 有一天邮差 A 到了邮局,Kenji 告诉他目前待处理的邮件有 100 封 接着 A 就开始从邮箱寻找他要负责处理的信件 然後邮差 B 也来了,Kenji 一样告诉他还剩下 100 封邮件 一样邮差 B 也去邮箱找信件 这时邮差 A 拿了他现在要处理的 20 封邮件离开, 告诉 Kenji 现在剩下 80 封 过了不久邮差 B 也拿了要处理的 30 封邮件 但他并不知道邮差 A 已经拿走了一些邮件,於是告诉 Kenji 现在剩下 70 封 Kenji 记录下现在的邮件数量:70,但很明显地我们知道实际上只剩下 50 封 这就是 multi-thread 同时对一个物件存取有可能产生错误的情境 为了避免这样的情形发生 以下我们要来介绍 synchronized 宣告的使用 Synchronized 的使用方法 1. Synchronized Method synchronized public void method1() { ... } 此种方法对於只有一个 instance 的 class 来说 能够确保在同一个时间只有一个 Thread 正在执行此 Method 但是如果 new 了很多 instance 出来就没有办法保证了 2. Synchronized Static Method synchronized public static void method2() { ... } 为上一种方法的加强版,就算有很多 instance 还是可以确保 同一时间只有一个 Thread 正在执行此 Method 3. Synchronized(this) public void method3() { ... synchronized(this) { ... } ... } 此种方法跟第一种方式类似 差别只是写在 synchronized(this) 之前的程式码可以同时被执行 synchronized(this) 之後的程式码同时只有一个 Thread 可执行 我知道这样讲完还是有点抽象 让我们来看看下面的例子! Synchronized 的实际例子 Synchronized.class 首先我们先建立一个 class 里面有四个 Method 1. method0(): 普通没有做 synchronized 的 method 2. method1(): 实作上面的 Synchronized Method 3. method2(): 实作上面的 Synchronized Static Method 4. method3(): 实作上面的 Synchronized(this) 做的事情很简单,只是每过一秒吐一个 Log 出来 并且显示现在正在执行的 Thread public class Synchronized { final static private String TAG = "Kenji"; public static void method0() { int i = 0; while (i++ < 3) { Log.d(TAG, Thread.currentThread().getName() + ":" + i); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } synchronized public void method1() { method0(); } synchronized public static void method2() { method0(); } public void method3() { Log.d(TAG, "Start method3"); synchronized (this) { method0(); } Log.d(TAG, "End method3"); } } MainActivity.class 接着我们在 MainActivity 新增两个 Thread 名字分别为 A 跟 B 接着观察执行不同的 method 时 Log 的变化 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final Synchronized mSynchronized = new Synchronized(); Thread thread1 = new Thread(new Runnable() { @Override public void run() { mSynchronized.method0(); // mSynchronized.method1(); // new Synchronized().method1(); // new Synchronized().method2(); // mSynchronized.method1(); } },"A"); Thread thread2 = new Thread(new Runnable() { @Override public void run() { mSynchronized.method0(); // mSynchronized.method1(); // new Synchronized().method1(); // new Synchronized().method2(); // mSynchronized.method3(); } }, "B"); Log.d("Kenji", "Start Thread!"); thread1.start(); thread2.start(); } 运行的结果如下: 1. 执行正常的 method 两个 thread A, B 会交错出现 thread1: mSynchronized.method0(); thread2: mSynchronized.method0(); -------------------------------------------- Start Thread! A:1 B:1 B:2 A:2 A:3 B:3 2. 执行 Synchronized method 会先等其中一个 thread 执行完 才会再度执行相同的程式码区块 thread1: mSynchronized.method1(); thread2: mSynchronized.method1(); -------------------------------------------- Start Thread! A:1 A:2 A:3 B:1 B:2 B:3 3. 但是如果有超过一个物件的话,程式码会同时执行 thread1: new Synchronized().method1(); thread2: new Synchronized().method1(); -------------------------------------------- Start Thread! B:1 A:1 A:2 B:2 A:3 B:3 4. 如果采用 Synchronized Static Method 的话 就可以解决上面同时执行的问题 thread1: new Synchronized().method2(); thread2: new Synchronized().method2(); -------------------------------------------- Start Thread! A:1 A:2 A:3 B:1 B:2 B:3 5. 写在 synchronized(this) 之前的程式码可以先同时执行 thread1: mSynchronized.method1(); thread2: mSynchronized.method3(); -------------------------------------------- Start Thread! A:1 Start method3 A:2 A:3 B:1 B:2 B:3 End method3 总结 Synchronized 宣告其实是在 multi-thread 中蛮值得学习的一些观念 以下是我对 Synchronized 的一些理解: 1. 只要有 thread 存取了某个 class 中的 synchronized method, 那麽其他的 thread 也不能存取整个 class 中所有的 synchronized method 也就是在同一个时间内只会有一个 method 存取 synchronized 区块的程式码 2. 相反的,当一个 thread 正在执行 synchronized 区块时 其他 thread 仍然可以执行 非synchronized 区块的程式码 希望对大家有帮助罗!谢谢! 参考资料: 1. java同步机制:synchronized http://blog.csdn.net/cjjky/article/details/7353390 2. 执行绪与 synchronized 同步函式的应用 http://dazi2012.blogspot.tw/2013/04/synchronized.html 3. [Java] Synchronized 心得 http://www.jackforfun.com/2007/07/java-synchronized.html --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 36.224.182.204
1F:推 Y78:推 01/21 23:15
2F:推 asadman1523:辛苦你了!还要排版好累 01/21 23:23
3F:→ punk86862001:排版真的有点麻烦QQ 01/21 23:25
4F:推 ian90911:推 01/22 18:37
5F:推 pttnews:谢谢原P ,你是个好人 01/23 15:15
6F:推 Killercat:最好别太依赖这种semaphore类型的保护 效能会很糟 01/23 18:24
7F:→ Killercat:应该先往thread safe或者thread local相容的方向着手 01/23 18:25
8F:→ Killercat:用synchornized是最後不得已的方法 而且目前来讲 01/23 18:25
9F:→ Killercat:看到的95%的synchornized都是可避免的居多 01/23 18:25
10F:→ Killercat:尤其是Thread local,这是个该善加利用的好东西 01/23 18:25
11F:→ asadman1523:请问那如果是银行那种存提款系统,该如何避免呢? 01/24 23:58
12F:推 youweit:学习了!很清楚地解释了synchronized 好文 01/27 19:53
13F:推 chadcoco1222:push 01/30 00:56
14F:推 jealdedani:推 02/01 21:34







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Boy-Girl站内搜寻

TOP