62,628
社区成员
发帖
与我相关
我的任务
分享public class ThreadDemo17 {
public static void main(String[] args) {
Send send=new Send();
Rec rec=new Rec(send);
Thread t1=new Thread(send);
Thread t2=new Thread(rec);
t1.start();
t2.start();
}
}
class Send implements Runnable {
boolean flag;
int theValue;
public void run() {
for (int i = 1; i <= 2; i++) {
System.out.println("发送者循环"+i+"次");
synchronized (this) {
System.out.println("发送者进入同步快 flag="+flag);
while (flag) { // why需要用while 存在中断和虚假唤醒
try {
this.wait(); //wait方法会释放同步块的钥匙
System.out.println("发送者等待");
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
// 生产者生产食物
for(int j=1;j<=10;j++){
System.out.println("A线程循环"+j+"次");
}
// 自己去等待
flag = true;
this.notify(); //唤醒消费者
}
System.out.println("发送者释放同步块");
}
}
}
class Rec implements Runnable {
private Send send;
public Rec(Send send) {
super();
this.send = send;
}
public void run() {
// 不知道生产者生产了多少食物,生产多少消费多少
for(int i=1;i<=2;i++) {
synchronized (send) {
System.out.println("接收者进入同步快 flag="+send.flag);
while (!send.flag) {
try {
send.wait();
System.out.println("发送者等待");
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
//消费食物
for(int j=1;j<=20;j++){
System.out.println("B线程循环"+j+"次");
}
//自己去等待
send.flag=false;
send.notify();
}
}
}
}
this.wait(); //wait方法会释放同步块的钥匙
wait方法,会释放对象的同步锁,所以你下面的:
synchronized (send)
就可以获取锁,进而继续执行了
同理:
send.wait();
这句话同样会释放send所指向的对象的锁,自然,你前面的:
synchronized (this)
也可以获取锁,继续执行了。
因为,你的Send里的this与Rec里的send是指向同一个对象