导读:
1、设置对象和打印对象的线程,其实我们应该写得更加纯粹,避免耦合;
2、竞争资源是 Student ,所以同步的代码逻辑应该写在竞争资源的类中,这样更合理。
代码:
1、竞争资源类
public class Student {
private String name;
private Integer age;
private Boolean flag=false;
public synchronized void set(String name,Integer age){
// 如果有数据,就等待
if(this.flag){
// 有数据,就等待
// 唤醒以后继续往下执行
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 设置数据
this.name = name;
this.age = age;
// 修改标记
this.flag = true;
this.notify();
}
public synchronized void get(){
// 如果没有数据,就等待
if(!this.flag){
//
try {
// 被唤醒以后继续往下执行
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("name => " + name + ",age=> "+ age);
// 修改标记
this.flag=false;
this.notify();
}
}
2、设置对象和获取对象的线程
public class GetThread implements Runnable {
private Student student;
public GetThread(Student student){
this.student = student;
}
@Override
public void run() {
while (true){
student.get();
}
}
}
public class SetThread implements Runnable {
private Student student;
private Integer x=0;
public SetThread(Student student){
this.student = student;
}
@Override
public void run() {
while (true){
if(x%2==0){
student.set("liwei",29);
}else {
student.set("zhouguang",30);
}
x++;
}
}
}
3、测试代码
/**
* Created by liwei on 16/7/19.
* 把 Student 的成员变量私有化
* 问题3:虽然数据安全了,但是呢,一次一大片不好看,我就想依次的一次一个输出。
* 如何实现呢?
* 通过Java提供的等待唤醒机制解决。
*
* 等待唤醒:
* Object类中提供了三个方法:
* wait():等待
* notify():唤醒单个线程
* notifyAll():唤醒所有线程
* 为什么这些方法不定义在Thread类中呢?
* 这些方法的调用必须通过锁对象调用,而我们刚才使用的锁对象是任意锁对象。
* 所以,这些方法必须定义在Object类中。
*
* 最终版代码中:
* 把Student的成员变量给私有的了。
* 把设置和获取的操作给封装成了功能,并加了同步。
* 设置或者获取的线程里面只需要调用方法即可。
*/
public class StudentDemo {
public static void main(String[] args) {
Student student = new Student();
GetThread getThread = new GetThread(student);
SetThread setThread = new SetThread(student);
Thread t1 = new Thread(getThread);
Thread t2 = new Thread(setThread);
t1.start();
t2.start();
}
}