作者:CSN | 来源:互联网 | 2023-10-10 09:34
当一个线程在就绪状态,拿到同步锁,调用(锁对象.wait())函数之后,让出锁,进入锁对象的等待池。如果这个时候,另一个线程占用锁,但是这时候调用了阻塞线程的interrupt()函数。阻塞线程并不会立即中断,它是等待别的线程让出锁之后,它抢到锁,再中断的。我做了一个实验如下。
package myThread;// 锁对象
class MyInterruptLock {}public class MyInterrupted {public static void main(String[] args){// 新建锁对象MyInterruptLock myInterruptLock = new MyInterruptLock();// 新建线程,让该线程调用wait()函数WaitThread waitThread = new WaitThread(myInterruptLock, true);// 新建线程,让该对象调用sleep()函数,不让出同步锁WaitThread waitThread1 = new WaitThread(myInterruptLock, false);Thread thread = new Thread(waitThread,"线程1");Thread thread1 = new Thread(waitThread1,"线程2");// 启动两个线程thread.start();thread1.start();// 让主线程休息3秒后,中断线程1,但是线程2占用了同步锁6秒,可以看出3秒后线程1// 并不会产生异常而中断,而是6秒后等待线程2执行完,让出锁,线程1抢到锁,才能// 产生异常而中断try {Thread.sleep(3000);thread.interrupt();} catch (InterruptedException e) {e.printStackTrace();}}
}class WaitThread implements Runnable {MyInterruptLock myInterruptLock;boolean flag;public WaitThread(MyInterruptLock myInterruptLock, boolean flag) {this.myInterruptLock = myInterruptLock;this.flag = flag;}@Overridepublic void run() {synchronized (myInterruptLock){System.out.println(Thread.currentThread().getName());if(flag){try {myInterruptLock.wait();} catch (InterruptedException e) {System.out.println("我拿到了锁");e.printStackTrace();}}else{try {Thread.sleep(6000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("我在占用锁");}}}
}