当前线程进入waiting状态,线程遇到中断时是否能立即获得monitor锁响应中断?

来源:7-5 wait解析

Panda_io

2019-10-11

package threadcoreknowledge.threadobjectclasscommonmethods;

import java.util.concurrent.TimeUnit;

/**
 * @Author: panda
 * @Description: 测试当线程进入waiting状态,线程遇到中断时是否能立即获得monitor锁响应中断
 *  结论:还是要等其他线程释放monitor锁后才能获得
 * @Date: 2019/10/11 10:31
 **/
public class WaitInterrupted {
    private static final Object lock = new Object();
    private class Wait implements Runnable{
        @Override
        public void run() {
            threadWait();
        }
    }

    private class Count implements Runnable{
        @Override
        public void run() {
            count();
        }
    }

    private  void count(){
        synchronized(lock){
            System.out.println(Thread.currentThread().getName()+"拿到了monitor锁");
            for (int i = 1 ; i <= 100000 ; i++){
                System.out.println(Thread.currentThread().getName() + " : " + i);
            }
            System.out.println(Thread.currentThread().getName()+"释放了monitor锁");
        }
    }

    private void  threadWait(){
        synchronized (lock){
            System.out.println(Thread.currentThread().getName()+"拿到了monitor锁");
            try {
                lock.wait();
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread().getName()+ "遇到中断线程状态从WAITING状态被唤醒成:"+ Thread.currentThread().getState());
                e.printStackTrace();
            }
            System.out.println("count这时候打印暂停,sleep不会释放当前锁");
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"释放了monitor锁");
            System.out.println("count继续打印剩下的数字");
        }
    }
    public Count getCount(){
        return new Count();
    }
    public Wait getWait(){
        return new Wait();
    }

    public static void main(String[] args)throws InterruptedException {
        WaitInterrupted waitInterrupted = new WaitInterrupted();
        Thread wait = new Thread(waitInterrupted.getWait(),"wait");
        wait.start();
        //让wait先执行
        TimeUnit.SECONDS.sleep(1);
        Thread count = new Thread(waitInterrupted.getCount(),"count");
        count.start();
        //让count线程先打印些数字出来再进行中断
        TimeUnit.SECONDS.sleep(1);
        wait.interrupt();
    }
}

输出结果:
图片描述

设想:当被同步的线程进入WAITING状态,当一遇到中断就会马上响应中断(立马获得锁)。

测试:这里建立了两个线程用同一把锁,第一个wait线程先获取到锁然后进入WAITING状态同时释放锁,接着count线程获得这把锁开始打印数字值到100000,同时让主线程休眠1秒保证先打印出一些数看到效果,然后产生一个中断。根据设想那么wait线程会立马获得锁,并进入休眠,并且不会释放锁,这时count线程停止打印直到wait线程sleep结束并释放锁,count再次获取锁继续打印剩下的数。

结论:根据输出可以看出,当产生一个中断后wait线程并没有立马获得锁,而只是被唤醒成RUNNABLE状态,等待锁被count线程释放,然后再次获取锁响应中断。

这个老师没有写demo,我就自己写一个来测试,如果不正确希望老师指正。

写回答

1回答

悟空

2019-10-11

必须要等到被唤醒后,并且拿到锁之后才能响应中断的,wait期间什么都做不了

0
6
悟空
回复
Panda_io
对的 原来的结论是正确的。恩,在家办公
2020-02-14
共6条回复

线程八大核心+Java并发原理及企业级并发解决方案

完整的并发知识网络+丰富的工作内容分享+50余道并发高频面试题

2512 学习 · 940 问题

查看课程