问题是这样的,就是我建了3个线程t1,t2,t3,然后分别在t1线程唤醒t2线程,t2线程唤醒t3,
t1唤醒t2的时候用的锁是一个无关的对象,然后t2唤醒t3的时候用的锁对象是t1这个线程的对象
遇到的问题是:t1唤醒t2的时候把t3也唤醒了
疑问的点在于:1.notify只能唤醒一个线程,为什么两个线程都被唤醒了,2.notify是唤醒当前锁对象锁住的线程t2和t3使用不一样的锁,为什么同时被唤醒了,3.为什么如果使用无关对象(如用第25行的Object对象)作为锁依然可以正常的保证唤醒顺序
package com.yyc;
import lombok.Data;
import org.junit.jupiter.api.Test;
import java.util.Vector;
//import org.openjdk.jol.info.ClassLayout;
/**
* @ClassName StudyThread
* @Description: TODO
* @Author huang.yuntao
* @Date 2020/12/15
* @Version V1.0
**/
public class StudyThread {
public static void main(String[] args) throws InterruptedException {
new StudyThread().methodOne();
}
public void methodOne() throws InterruptedException {
Vector<Cat> vector = new Vector();
int size = 30;
Object o = new Object();
Thread ti = new Thread(()->{
for (int i = 0; i < size; i++) {
Cat cat = new Cat(i);
vector.add(cat);
// System.out.println(ClassLayout.parseInstance(cat).toPrintable());
synchronized (cat){
// System.out.println(Thread.currentThread().getName()+"========="+i+"========="+ClassLayout.parseInstance(cat).toPrintable());
}
}
synchronized (vector){
vector.notify();
}
},"11111");
ti.start();
Thread t2 = new Thread(()->{
synchronized (vector){
try {
System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-------2");
vector.wait();
System.out.println("###################################-----2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < size; i++) {
Cat cat = vector.get(i);
// System.out.println(ClassLayout.parseInstance(cat).toPrintable());
synchronized (cat){
// System.out.println(Thread.currentThread().getName()+"========="+i+"========="+ClassLayout.parseInstance(cat).toPrintable());
}
}
synchronized (ti){
ti.notify();
}
},"22222");
t2.start();
Thread t3 = new Thread(()->{
synchronized (ti){
try {
System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-------3");
ti.wait();
System.out.println("###################################-----3");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < size; i++) {
Cat cat = vector.get(i);
// System.out.println(ClassLayout.parseInstance(cat).toPrintable());
synchronized (cat){
// System.out.println(Thread.currentThread().getName()+"========="+i+"========="+ClassLayout.parseInstance(cat).toPrintable());
}
}
},"333");
t3.start();
}
@Data
private class Cat{
public Cat(int id) {
this.id = id;
}
private int id;
}
}