Object类中提供了三个方法
- wait()等待
- notify() 唤醒单个线程
- notifyAll() 唤醒所有线程
public class Student {
String name;
int age;
boolean flag;
}
public class SetThread implements Runnable {
private Student s;
private int x = 0;
public SetThread(Student s) {
this.s = s;
}
@Override
public void run() {
while (true) {
//注意:加锁必须是同一把
synchronized(s){//加锁同时获取的也应该加锁
if(s.flag){
try {
s.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (x % 2 == 0) {
s.name = "0";
s.age = 19;
} else {
s.name = "1";//这里是有线程问题的。线程一走进来接着又走进来一个线程二,内存就会有改变,所以要加锁
s.age = 25;
}
x++;
//修改标记
s.flag=true;
//唤醒
s.notify();
}
}
}
}
public class GetThread implements Runnable {
private Student s;
public GetThread(Student s) {
this.s = s;
}
@Override
public void run() {
while (true) {
//注意:加锁必须是同一把
synchronized(s){
if(!s.flag) {//没有东西为true
try {
s.wait();//等待,立即释放锁,将来唤醒从这里唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(s.name + "---" + s.age);
//修改标记
s.flag=false;
//唤醒
s.notify();
}
}
}
}
/*
* 线程安全问题:
* A:是否是多线程
* B:是否是共享数据
* C:是否是多条语句操作数据
* */
public class StudentDemo {
public static void main(String[] args) {
Student s=new Student();
SetThread st=new SetThread(s);
GetThread gt=new GetThread(s);
Thread t=new Thread(st);
Thread t2=new Thread(gt);
t.start();
t2.start();
}
}