PriestM 2017-11-16 07:50 采纳率: 100%
浏览 1117
已结题

java多线程中关于使用notify()方法的几个疑问

代码:

public class NotifyAndWaitTest2 implements Runnable {
    public int i = 0;
    public Object lock;
    public SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");

    public NotifyAndWaitTest2(Object o) {
        this.lock = o;
    }

    @Override
    public void run() {
        synchronized (lock) {
            System.out.println(Thread.currentThread().getName() + " enter the SYNCHRONIZED block --- "+ sdf.format(new Date()));
            try {
                while (i < 9) {
                    Thread.sleep(500);
                    lock.notify();
                    lock.wait();
                    System.out.println(Thread.currentThread().getName() + " say:" + i++ + " --- " + sdf.format(new Date()));
                }
                lock.notify();
                return;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Object lock = new Object();
        NotifyAndWaitTest2 test = new NotifyAndWaitTest2(lock);
        Thread t1 = new Thread(test,"Thread A");
        Thread t2 = new Thread(test,"Thread B");
        Thread t3 = new Thread(test,"Thread C");
        Thread t4 = new Thread(test,"Thread D");
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}

执行结果:

Thread A enter the SYNCHRONIZED block --- 10:47:07.242
Thread B enter the SYNCHRONIZED block --- 10:47:07.743
Thread C enter the SYNCHRONIZED block --- 10:47:08.243
Thread D enter the SYNCHRONIZED block --- 10:47:08.743
Thread C say:0 --- 10:47:09.243
Thread D say:1 --- 10:47:09.744
Thread C say:2 --- 10:47:10.244
Thread D say:3 --- 10:47:10.744
Thread C say:4 --- 10:47:11.245
Thread D say:5 --- 10:47:11.745
Thread C say:6 --- 10:47:12.246
Thread D say:7 --- 10:47:12.746
Thread C say:8 --- 10:47:13.247
Thread D say:9 --- 10:47:13.247
Thread B say:10 --- 10:47:13.247
Thread A say:11 --- 10:47:13.247

这段代码我在 jdk1.7 和 jdk1.8 中都执行过,结果是"相同的"

我主要有两个问题:(以我贴出的这个执行结果为例)

1、在线程A 和线程B 进入了同步代码块之后,并且线程B 调用了 wait() 方法,为什么接下来一定是另外两个线程进入同步代码块?而不是线程A 开始打印 say。是"让新的线程进入同步代码块"的优先级比"调用wait()方法的线程被唤醒"的优先级高吗?

2、为什么调用 notify() 方法只能唤醒最后一个调用了 wait() 方法的线程?就像上面这个执行结果,只有线程C 和线程D 互相唤醒对方,为什么不能唤醒其他的线程,比如线程A 和线程B?

我认为抢对象锁应该是不规律的、随机的,比如这样:

Thread A enter the SYNCHRONIZED block
Thread B enter the SYNCHRONIZED block
Thread A say:0
Thread C enter the SYNCHRONIZED block
Thread B say:1
Thread A say:2
Thread D enter the SYNCHRONIZED block
Thread B say:3
Thread C say:4
  • 写回答

1条回答

  • 夜空中的程序猿 2017-11-17 07:21
    关注

    理论上是随机的,哪个抢到cpu资源就执行哪个,线程初始化的时候会设置默认优先级为5,可以通过设置线程优先级让线程更有抢的cpu资源的优势,但是也只是相对随机的,代码实现的时候就当成随机,不要依赖这一点就行了,Thread类有三个静态变量可以设置线程执行优先级分别为高中低
    Thread.MAX_PRIORITY;
    Thread.MIN_PRIORITY;
    Thread.NORM_PRIORITY;

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3