010.多執行緒-執行緒間通訊
阿新 • • 發佈:2018-12-21
多執行緒之間的通訊,其實就是多個執行緒同時操作(讀+寫)同一個資源。
安全問題:
當執行緒在讀取資源的過程中,寫執行緒操作了資源,
導致讀執行緒讀取的資料,一部分是寫之前的資料,一部分是寫之後的資料。
解決安全問題:
讀執行緒和寫執行緒使用同一把物件鎖就好了。
code of demo:
package cn.qbz.thread;
/**
* 執行緒間通訊
*/
public class ConnectThreadTest {
public static void main(String[] args) {
Student student = new Student ();
ProduceTest produceTest = new ProduceTest(student);
ConsumerTest consumerTest = new ConsumerTest(student);
produceTest.start();
consumerTest.start();
}
}
class ProduceTest extends Thread {
private Student student;
public ProduceTest(Student student) {
this.student = student;
}
@Override
public void run() {
int num = 1;
while (true) {
synchronized (student) {
//如果可以生產,生產者生產
if (student.getCanProduce()) {
if (num == 1) {
student. setAge(6);
student.setName("小王");
num = 0;
} else {
student.setName("老王");
student.setAge(99);
num = 1;
}
//重置生產者不可以生產
student.setCanProduce(false);
}
student.notifyAll();
try {
student.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
class ConsumerTest extends Thread {
private Student student;
public ConsumerTest(Student student) {
this.student = student;
}
@Override
public void run() {
while (true) {
synchronized (student) {
//如果不可以生產,進行消費
if (!student.getCanProduce()) {
//重置生產者可以生產
student.setCanProduce(true);
System.out.println(student.toString());
}
student.notifyAll();
try {
student.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
class Student {
private String name;
private Integer age;
private Boolean canProduce = false;
public Boolean getCanProduce() {
return canProduce;
}
public void setCanProduce(Boolean canProduce) {
this.canProduce = canProduce;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}