a351144b 2020-12-17 14:15 采纳率: 100%
浏览 16
已采纳

多线程唤醒的异常问题

问题是这样的,就是我建了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;
    }
}

  • 写回答

3条回答 默认 最新

  • boylilz 2020-12-17 15:39
    关注

    你线程t3等待的对象不对,换成

    vector或者重新定义一个对象,ti为线程对象
    1 线程对象的wait()方法运行后,可以不用其notify()方法退出,会在线程结束后,自动退出。
     2 线程间的等待唤醒机制,最好不要用线程对象做同步锁!
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)
  • ¥15 AIC3204的示例代码有吗,想用AIC3204测量血氧,找不到相关的代码。