从头认识多线程-2.10 同步代码块的特殊现象:一半同步,一半异步

来源:互联网 发布:锐捷网络2016年销售额 编辑:程序博客网 时间:2024/05/29 04:48

这一章节我们来讨论一下同步代码块的一个特殊现象:一半同步,一半异步

1.代码清单:

1)目的:展示同步代码块的同步与异步并存的现象

2)代码功能说明:

(1)建立一个测试类

(2)创建三个属性域

(3)创建三个方法,一个同步,两个不同步

(4)方法的内容是输出整数相加的结果以及相应的线程名称

(5)使用两个线程同时访问

package com.ray.deepintothread.ch02.topic_10;/** *  * @author RayLee * */public class SynchAndAsynch {public static void main(String[] args) throws InterruptedException {MyService myService = new MyService();ThreadOne threadOne = new ThreadOne(myService);Thread thread = new Thread(threadOne);thread.start();ThreadTwo threadTwo = new ThreadTwo(myService);Thread thread2 = new Thread(threadTwo);thread2.start();}}class ThreadOne implements Runnable {private MyService myService;public ThreadOne(MyService myService) {this.myService = myService;}@Overridepublic void run() {myService.update();}}class ThreadTwo implements Runnable {private MyService myService;public ThreadTwo(MyService myService) {this.myService = myService;}@Overridepublic void run() {myService.update();}}class MyService {private int a = 0;private int b = 0;private int c = 0;private void updateA() {for (int i = 0; i < 10; i++) {System.out.println("Thread name:" + Thread.currentThread().getName() + " a:" + a++);try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}}}/** * 增加同步 */private void updateB() {for (int i = 0; i < 10; i++) {System.out.println("Thread name:" + Thread.currentThread().getName() + " b:" + b++);try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}private void updateC() {for (int i = 0; i < 10; i++) {System.out.println("Thread name:" + Thread.currentThread().getName() + " c:" + c++);try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}public void update() {updateA();synchronized (this) {updateB();}updateC();}}

输出:

Thread name:Thread-0 a:0
Thread name:Thread-1 a:1
Thread name:Thread-1 a:2
Thread name:Thread-0 a:2
Thread name:Thread-1 a:3
Thread name:Thread-0 a:4
Thread name:Thread-0 a:6
Thread name:Thread-1 a:5
Thread name:Thread-0 a:7
Thread name:Thread-1 a:8
Thread name:Thread-0 a:9
Thread name:Thread-1 a:10
Thread name:Thread-1 a:11
Thread name:Thread-0 a:12
Thread name:Thread-1 a:13
Thread name:Thread-0 a:14
Thread name:Thread-1 a:15
Thread name:Thread-0 a:16
Thread name:Thread-1 a:17
Thread name:Thread-0 a:18

------------------------------------------(人为分隔符)
Thread name:Thread-1 b:0
Thread name:Thread-1 b:1
Thread name:Thread-1 b:2
Thread name:Thread-1 b:3
Thread name:Thread-1 b:4
Thread name:Thread-1 b:5
Thread name:Thread-1 b:6
Thread name:Thread-1 b:7
Thread name:Thread-1 b:8
Thread name:Thread-1 b:9

------------------------------------------(人为分隔符)
Thread name:Thread-0 b:10

Thread name:Thread-1 c:0

Thread name:Thread-0 b:11
Thread name:Thread-1 c:1
Thread name:Thread-1 c:2
Thread name:Thread-0 b:12
Thread name:Thread-0 b:13
Thread name:Thread-1 c:3
Thread name:Thread-1 c:4
Thread name:Thread-0 b:14
Thread name:Thread-1 c:5
Thread name:Thread-0 b:15
Thread name:Thread-0 b:16
Thread name:Thread-1 c:6
Thread name:Thread-1 c:7
Thread name:Thread-0 b:17
Thread name:Thread-0 b:18
Thread name:Thread-1 c:8
Thread name:Thread-1 c:9
Thread name:Thread-0 b:19

------------------------------------------(人为分隔符)
Thread name:Thread-0 c:10
Thread name:Thread-0 c:11
Thread name:Thread-0 c:12
Thread name:Thread-0 c:13
Thread name:Thread-0 c:14
Thread name:Thread-0 c:15
Thread name:Thread-0 c:16
Thread name:Thread-0 c:17
Thread name:Thread-0 c:18
Thread name:Thread-0 c:19


2.分析

我们把上面的输出分为4段:

(1)第一段

Thread name:Thread-0 a:0
Thread name:Thread-1 a:1
Thread name:Thread-1 a:2
Thread name:Thread-0 a:2
Thread name:Thread-1 a:3
Thread name:Thread-0 a:4
Thread name:Thread-0 a:6
Thread name:Thread-1 a:5
Thread name:Thread-0 a:7
Thread name:Thread-1 a:8
Thread name:Thread-0 a:9
Thread name:Thread-1 a:10
Thread name:Thread-1 a:11
Thread name:Thread-0 a:12
Thread name:Thread-1 a:13
Thread name:Thread-0 a:14
Thread name:Thread-1 a:15
Thread name:Thread-0 a:16
Thread name:Thread-1 a:17
Thread name:Thread-0 a:18

这一段输出结合代码我们可以知道,这个时候是两个线程同时访问updateA这个方法,由于该方法没有做同步,因此会出现上面的间隔的输出


(2)第二段

Thread name:Thread-1 b:0
Thread name:Thread-1 b:1
Thread name:Thread-1 b:2
Thread name:Thread-1 b:3
Thread name:Thread-1 b:4
Thread name:Thread-1 b:5
Thread name:Thread-1 b:6
Thread name:Thread-1 b:7
Thread name:Thread-1 b:8
Thread name:Thread-1 b:9

这一段输出,由于updateB做了同步,这个时候Thread-1拿到锁,因此Thread-0想访问updateB就不行,只好等Thread-1执行完成才可以。


(3)第三段

Thread name:Thread-0 b:10

Thread name:Thread-1 c:0

Thread name:Thread-0 b:11
Thread name:Thread-1 c:1
Thread name:Thread-1 c:2
Thread name:Thread-0 b:12
Thread name:Thread-0 b:13
Thread name:Thread-1 c:3
Thread name:Thread-1 c:4
Thread name:Thread-0 b:14
Thread name:Thread-1 c:5
Thread name:Thread-0 b:15
Thread name:Thread-0 b:16
Thread name:Thread-1 c:6
Thread name:Thread-1 c:7
Thread name:Thread-0 b:17
Thread name:Thread-0 b:18
Thread name:Thread-1 c:8
Thread name:Thread-1 c:9
Thread name:Thread-0 b:19

这一段也是间隔输出,但其中的原理跟第一段其实是不一样的。

对于Thread-0,由于上一阶段没有拿到锁,这个阶段才拿到,因此,它还在同步的执行updateB这个方法

对于Thread-1,由于上一阶段已经完成同步方法,这个阶段执行不同步的updateC,所以会间隔的穿插输入

这一阶段就是我们所需要展示的一半同步,一半异步的现象


(4)第四段

Thread name:Thread-0 c:10
Thread name:Thread-0 c:11
Thread name:Thread-0 c:12
Thread name:Thread-0 c:13
Thread name:Thread-0 c:14
Thread name:Thread-0 c:15
Thread name:Thread-0 c:16
Thread name:Thread-0 c:17
Thread name:Thread-0 c:18
Thread name:Thread-0 c:19

虽然看上去跟第二段差不多,但是原理也是不一样

这里只是Thread-1已经完成了所有功能,只剩下Thread-0的执行了。


总结:这一章节展示了不同步、同步以及一半半的情况。


这一章节就到这里,谢谢

------------------------------------------------------------------------------------

我的github:https://github.com/raylee2015/DeepIntoThread


目录:http://blog.csdn.net/raylee2007/article/details/51204573


0 0
原创粉丝点击