java多线程系列--AQS-02之锁中断
来源:互联网 发布:炫云客户端知乎 编辑:程序博客网 时间:2024/05/29 04:35
锁中断的概念
个人理解就是在一定时间内如果线程还未能获取到锁,我们可以对其进行中断处理并且线程能感知到这一行为的发生(这里的中断并不是说立刻停止线程而是让线程感知到然后我们在进行一些相应的处理比如break、return)
synchronized不支持锁的中断
public class SynchronizedIntercept { final static Object synchronizedObj=new Object(); public static void main(String[] args) throws InterruptedException { Thread thread01=new Thread(new Runnable() { @Override public void run() { synchronized (synchronizedObj) { try { Thread.sleep(Integer.MAX_VALUE); } catch (InterruptedException e) { e.printStackTrace(); } } } }); //先启动线程01,然后一直占用锁 thread01.start(); Thread.sleep(1000L); Thread thread02=new Thread(new Runnable() { @Override public void run() { synchronized (synchronizedObj) { System.out.println("=========我是线程thread02======"); } } }); //然后启用线程2,让其永远也无法获取到锁 thread02.start(); Thread.sleep(1000L); //对线程进行中断 thread02.interrupt(); //打印线程的状态 System.out.println(thread02.getState());//BLOCKED }}
我们发现thread02.interrupt()操作不起任何作用,这也验证synchronized不支持锁的中断这一结论
ReentrantLock中lockInterruptibly()支持中断
import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class LockInterceptor { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(new RunIt()); Thread t2 = new Thread(new RunIt()); t1.start(); Thread.sleep(2000L); t2.start(); t2.interrupt(); } } class RunIt implements Runnable{ private static Lock lock = new ReentrantLock(); @Override public void run() { try { runJob(); } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName()+" Interrrupted from runJob."); } } private void runJob() throws InterruptedException{ lock.lockInterruptibly(); System.out.println(Thread.currentThread().getName()+" 到此一游...."); try{ System.out.println(Thread.currentThread().getName() + " running"); TimeUnit.SECONDS.sleep(3); System.out.println(Thread.currentThread().getName() + " finished"); }catch(InterruptedException e){ System.out.println(Thread.currentThread().getName() + " interrupted"); }finally{ lock.unlock(); } } }
不要将lock()、lockInterruptibly()写在try()方法里面,因为如果写在里面,此时线程并没有得到锁只是阻塞在这里,然后如果线程被中断,那么将执行finally{lock.unlock(); }代码。由于没有获取到锁却调用释放锁的方法,代码肯定会报异常的
lockInterruptibly()支持中断源码分析
上篇文章我们介绍过lock()方法,知道了它是不支持中断的,因为就算线程被中断,lock()只会继续尝试获取锁而不会直接跳出循环,我们看下lockInterruptibly()是如何处理的
public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1);}public final void acquireInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (!tryAcquire(arg)) doAcquireInterruptibly(arg);}
我们可以看到在试图获取锁的时候最先就判断是否被中断,如果被中断就直接抛异常。如果没有获取到锁则执行doAcquireInterruptibly(arg)
private void doAcquireInterruptibly(int arg) throws InterruptedException { final Node node = addWaiter(Node.EXCLUSIVE); boolean failed = true; try { for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) { setHead(node); p.next = null; // help GC failed = false; return; } //这里才是重点,如果从park()中被中断唤醒则直接抛异常跳出死循环 if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) throw new InterruptedException(); } } finally { if (failed) cancelAcquire(node); } }
lockInterruptibly()获取不到锁会调用doAcquireInterruptibly(),在被阻塞的情况下被唤醒那么将直接抛出throw new InterruptedException();来中断循环。
lock()获取不到锁会调用acquireQueued().
我们可以看到在park后然后被中断唤醒后并没有跳出循环,这也是为啥lock()不支持中断的原因.
0 0
- java多线程系列--AQS-02之锁中断
- java多线程系列--AQS-01之独占锁原理浅析
- java多线程 之 AQS
- Java并发编程系列之九:AQS
- Java并发编程系列之五:AQS
- 多线程之AQS原理
- Java多线程系列(六)—AQS源码分析
- JAVA多线程系列--ReentrantLock实现原理-AQS详解
- 我之见--java多线程之可重入锁,读写锁源码分析 及自定义锁AQS
- Java并发之AQS
- Java多线程之线程中断
- JAVA并发编程学习笔记之AQS源码分析(超时、中断与其他)
- JAVA并发编程学习笔记之AQS源码分析(超时、中断与其他)
- JAVA并发编程学习笔记之AQS源码分析(超时、中断与其他)(r)
- Java并发之AQS详解
- Java并发之AQS详解
- Java并发之AQS详解
- Java并发之AQS详解
- 第7天:数据清洗(1)
- 17.5.2 经典相关分析(Canonical Correlation Analysis, CCA)
- AI 工程师的知识结构
- 在HTML中使用object和embed标签插入视频
- 这些年看过的技术书
- java多线程系列--AQS-02之锁中断
- 第8天:数据清洗(2)文本处理
- HashMap与HashTable的区别
- 《Wide and Deep Learning for Recommender Systems》学习笔记
- Java总结篇系列:Java多线程(一)
- 文本处理初学笔记01-主题模型
- python入门汇总
- 第9天:正则表达式
- python 实现周志华 机器学习书中 k-means 算法