直接上代码吧,这是一个小Demo,生产者和消费者
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();
}
} }}这段代码的开始运行结果是:
发送者循环1次
接收者进入同步快 flag=false
发送者进入同步快 flag=false
A线程循环1次
A线程循环2次
A线程循环3次
A线程循环4次
A线程循环5次
A线程循环6次
...
问题在于,代码中不是给接收者进行同步了吗(见代码synchronized (send){......}),相当于和发送者的synchronized (this)是加的同一把锁的,为什么接收者和发送者都可以进入同步快呢?
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();
}
} }}这段代码的开始运行结果是:
发送者循环1次
接收者进入同步快 flag=false
发送者进入同步快 flag=false
A线程循环1次
A线程循环2次
A线程循环3次
A线程循环4次
A线程循环5次
A线程循环6次
...
问题在于,代码中不是给接收者进行同步了吗(见代码synchronized (send){......}),相当于和发送者的synchronized (this)是加的同一把锁的,为什么接收者和发送者都可以进入同步快呢?
同理:send.wait();这句话同样会释放send所指向的对象的锁,自然,你前面的: synchronized (this) 也可以获取锁,继续执行了。因为,你的Send里的this与Rec里的send是指向同一个对象