您的位置:首页 > 移动开发 > Objective-C

从头认识多线程-2.14 解决由同步的synchronized (newobject()) 引起的脏读的方法

2016-05-08 14:22 465 查看
这一章节我们来讨论一下解决由同步的synchronized (newobject()) 引起的脏读的方法。
1.造成上面脏读的原因:多线程多方法同时访问并修改某个属性域

2.解决思路
顺着上面的原因,笔者提出两种不是方法的方法
(1)只能单线程单方法访问并修改某个属性域这样就保证了执行的顺序(也就是需要同步所有访问并修改的步骤)(缺点:性能低下,优点:数据的强一致性)
(2)在多线程多方法的情况下,只能够访问多个属性域,不能够同时访问并修改某一个单一的属性域(根本目的就是分开运算,但是,在生产环境中,的确很难把一个属性域分成2个来运算,所以,笔者更趋向于第一种方法)

3.代码清单
(1)第一个思路

package com.ray.deepintothread.ch02.topic_15;

/**
*
* @author RayLee
*
*/
public class SolutionOfDirtyRead {
public static void main(String[] args) throws InterruptedException {
MyService2 myService = new MyService2();
ThreadThree threadThree = new ThreadThree(myService);
Thread thread = new Thread(threadThree);
thread.start();
ThreadFour threadFour = new ThreadFour(myService);
Thread thread2 = new Thread(threadFour);
thread2.start();
}
}

class ThreadThree implements Runnable {

private MyService2 myService;

public ThreadThree(MyService2 myService) {
this.myService = myService;
}

@Override
public void run() {
try {
myService.update();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

class ThreadFour implements Runnable {

private MyService2 myService;

public ThreadFour(MyService2 myService) {
this.myService = myService;
}

@Override
public void run() {
try {
myService.update();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

class MyService2 {

private Integer id = 0;

public void updateA() throws InterruptedException {
synchronized (id) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " " + id++);
Thread.sleep(50);
}
}
}

public void updateB() throws InterruptedException {
synchronized (id) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " " + id++);
Thread.sleep(100);
}
}
}

public synchronized void update() throws InterruptedException {
updateA();
updateB();
}

}

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

我们把updateA和updateB组合成为一个方法, 然后做方法级的同步,或者将两个方法组合成方法块的同步,这样,输出的结果就可以是同步的,不会出现脏读

(2)第二种思路

package com.ray.deepintothread.ch02.topic_15;

/**
*
* @author RayLee
*
*/
public class SolutionOfDirtyRead2 {
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() {
try {
myService.updateA();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

class ThreadTwo implements Runnable {

private MyService myService;

public ThreadTwo(MyService myService) {
this.myService = myService;
}

@Override
public void run() {
try {
myService.updateB();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

class MyService {

private Integer id1 = 0;

private Integer id2 = 0;

public void updateA() throws InterruptedException {
synchronized (this) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " id1:" + id1++);
Thread.sleep(50);
}
}
}

public void updateB() throws InterruptedException {
synchronized (this) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " id2:" + id2++);
Thread.sleep(100);
}
}
}

}

输出:
Thread-0 id1:0
Thread-0 id1:1
Thread-0 id1:2
Thread-0 id1:3
Thread-0 id1:4
Thread-1 id2:0
Thread-1 id2:1
Thread-1 id2:2
Thread-1 id2:3
Thread-1 id2:4

虽然输出的结果是同步的,但是也是上面所说的,一个属性域(一般是某个数的运算或者某种状态的运算)是很难分开来的。当然,如果可以分开来,这是最优解,因为既保证了同步,也保证了数据的强一致性。

总结:这一章节主要讨论了解决由同步的synchronized (newobject()) 引起的脏读的方法。

这一章节就到这里,谢谢
------------------------------------------------------------------------------------
我的github:https://github.com/raylee2015/DeepIntoThread

目录:/article/7548544.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: