这一章节我们来讨论一下同步代码块的一个特殊现象:一半同步,一半异步
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; } @Override public void run() { myService.update(); } } class ThreadTwo implements Runnable { private MyService myService; public ThreadTwo(MyService myService) { this.myService = myService; } @Override public 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