멀티스레드 처음 인식-2.3 더티(dirty Read)
4529 단어 다중 스레드
1.왜 더러운 독서가 나오는가?
코드가 동기화되지 않았기 때문에 set 방법이 동기화되었지만 get 방법은 일반적으로 잊어버리기 때문에 읽은 값이 쓰여진 것입니다
2. 코드 목록
(1) 프로그램이 동기화되지 않고 너무 빨리 실행되어 더티(dirty) 읽기
package com.ray.deepintothread.ch02.topic_4;
public class DirtyRead {
public static void main(String[] args) throws InterruptedException {
MyTestObjectOne myTestObjectOne = new MyTestObjectOne();
ThreadOne threadTwo = new ThreadOne(myTestObjectOne);
Thread thread = new Thread(threadTwo);
thread.start();
System.out.println("id:" + myTestObjectOne.getId() + " name:" + myTestObjectOne.getName());
}
}
class ThreadOne implements Runnable {
private MyTestObjectOne myTestObjectOne;
public ThreadOne(MyTestObjectOne myTestObjectOne) {
this.myTestObjectOne = myTestObjectOne;
}
@Override
public void run() {
myTestObjectOne.setId(1);
myTestObjectOne.setName("ray");
}
}
class MyTestObjectOne {
private int id = 0;
private String name = "init";
public int getId() {
return id;
}
public synchronized void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public synchronized void setName(String name) {
this.name = name;
}
}
출력:
id:0 name:init
동기화되지 않았기 때문에 set의 라인이 시작될 때 get이 초기화된 값을 나타냅니다
(2) 동기화되지 않아 코드의 실행 선후 순서와 실행 시간을 제어할 수 없기 때문에 읽은 값은 이미 수정된 것이다
package com.ray.deepintothread.ch02.topic_4;
public class DirtyRead2 {
public static void main(String[] args) throws InterruptedException {
MyTestObjectTwo myTestObjectTwo = new MyTestObjectTwo();
ThreadTwo threadTwo = new ThreadTwo(myTestObjectTwo);
Thread thread = new Thread(threadTwo);
thread.start();
Thread.sleep(100);// , ,
System.out.println("id:" + myTestObjectTwo.getId() + " name:" + myTestObjectTwo.getName());
}
}
class ThreadTwo implements Runnable {
private MyTestObjectTwo myTestObjectTwo;
public ThreadTwo(MyTestObjectTwo myTestObjectTwo) {
this.myTestObjectTwo = myTestObjectTwo;
}
@Override
public void run() {
myTestObjectTwo.setId(1);
try {
Thread.sleep(1000);//
} catch (InterruptedException e) {
e.printStackTrace();
}
myTestObjectTwo.setName("ray");
}
}
class MyTestObjectTwo {
private int id = 0;
private String name = "init";
public int getId() {
return id;
}
public synchronized void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public synchronized void setName(String name) {
this.name = name;
}
}
출력:
id:1 name:init
출력에서 id가 수정되었지만,name를 수정하지 않았을 때, 이미 읽기 시작했음을 알 수 있습니다.
3. 솔루션 - 동기화, 그리고 기교 있는 동기화
package com.ray.deepintothread.ch02.topic_4;
public class DirtyRead3 {
public static void main(String[] args) throws InterruptedException {
MyTestObjectThree myTestObjectThree = new MyTestObjectThree();
ThreadThree threadThree = new ThreadThree(myTestObjectThree);
Thread thread = new Thread(threadThree);
thread.start();
ThreadFour threadFour = new ThreadFour(myTestObjectThree);
Thread thread1 = new Thread(threadFour);
thread1.start();
}
}
class ThreadThree implements Runnable {
private MyTestObjectThree myTestObjectThree;
public ThreadThree(MyTestObjectThree myTestObjectThree) {
this.myTestObjectThree = myTestObjectThree;
}
@Override
public void run() {
myTestObjectThree.setValue(1, "ray");
}
}
class ThreadFour implements Runnable {
private MyTestObjectThree myTestObjectThree;
public ThreadFour(MyTestObjectThree myTestObjectThree) {
this.myTestObjectThree = myTestObjectThree;
}
@Override
public void run() {
myTestObjectThree.getValue();
}
}
class MyTestObjectThree {
private int id = 0;
private String name = "init";
public synchronized void setValue(int id, String name) {
this.id = id;
this.name = name;
}
public synchronized void getValue() {
System.out.println("id:" + id + " name:" + name);
}
}
출력:
id:1 name:ray
동기화는 확실히 위의 문제를 해결할 수 있지만 주의해야 할 것은 위의 set 방법은 두 속성을 함께 설정한 것이다. 만약에 분리된다면 안 된다. 같은 이치로 get의 방법은 둘을 동시에 얻을 수 있고 분리하는 것은 안 된다.
총괄: 이 장에서 우리는 더러운 독서의 형성과 해결 방안을 토론했다.
이 장은 여기까지입니다. 감사합니다.
------------------------------------------------------------------------------------
내 github:https://github.com/raylee2015/DeepIntoThread
디렉토리:http://blog.csdn.net/raylee2007/article/details/51204573
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Java 다중 스레드를 순차적으로 실행하는 몇 가지 방법 요약Java 다중 스레드를 순차적으로 실행하는 몇 가지 방법 요약 동료는 무심결에 이 문제를 제기하고 두 가지 방법을 직접 실천했다.물론 더 좋은 방법이 있을 거야. 방법 1 이런 방법은 비교적 흔히 볼 수 있는 해결 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.