并发编程:锁重入与锁异常
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并发编程:锁重入与锁异常相关的知识,希望对你有一定的参考价值。
1、synchronized重入
关键字synchronized拥有锁重入的功能,也就是在使用synchronized时,当一个线程得到了一个对象的锁后,再次请求此对象时是可以再次得到该对象的锁。
1.1 同步方法间的调用
public class Demo5 { public synchronized void method1() throws InterruptedException { System.out.println("method..."); method2(); Thread.sleep(2000); } public synchronized void method2() throws InterruptedException { System.out.println("method2..."); method3(); Thread.sleep(2000); } public synchronized void method3() throws InterruptedException { System.out.println("method3..."); Thread.sleep(2000); } public static void main(String[] args) { final Demo5 demo5 = new Demo5(); Thread t1 = new Thread(new Runnable() { @Override public void run() { try { demo5.method1(); } catch (InterruptedException e) { e.printStackTrace(); } } }); t1.start(); } }
效果:
此处无须等待method1释放锁,method2、method3亦可执行。
1.2 父子同步方法的调用
public class Demo5_2 { static class Main { public int i = 10; public synchronized void operationSup(){ try { i--; System.out.println("父 print i = " + i); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } static class Sub extends Main { public synchronized void operationSub(){ try { while(i > 0) { i--; System.out.println("子 print i = " + i); Thread.sleep(100); this.operationSup(); } } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { @Override public void run() { Sub sub = new Sub(); sub.operationSub(); } }); t1.start(); } }
效果:
2、锁异常
出现异常,锁会自动释放
对于web应用程序,异常释放锁的情况,如果不及时处理,很可能对应用程序业务逻辑产生严重的错误,比如现在执行一个队列任务,很多对象都去在等待第一个对象正确执行完毕再去释放锁,但是第一个对象由于异常的出现,导致业务逻辑没有正常执行完毕,就释放了锁,那么可想而知后续的对象执行的都是错误的逻辑。所以一定要引起注意,在编写代码的时候,一定要考虑周全。
public class Demo6 { private int i = 0; public synchronized void method() { while(true) { try { i++; Thread.sleep(200); System.out.println(Thread.currentThread().getName() + " , i = " + i); if (i == 3) { Integer.parseInt("a"); // throw new RuntimeException(); } } catch (Exception e) { // InterruptedException e.printStackTrace(); System.out.println(" log info i = " + i); //throw new RuntimeException(); //continue; } } } public static void main(String[] args) { final Demo6 demo6 = new Demo6(); Thread t1 = new Thread(new Runnable() { @Override public void run() { demo6.method(); } }, "t1"); t1.start(); } }
说明:当i=3的时候,Integer.parseInt("a");出现异常了,但是后续还在执行,这并不是我们想要的结果。
解决思路:
第一种:在异常块里记录日志
第二种:抛出运行时异常,throw new RuntimeException();
第三种:打断InterruptedException
效果:第二种
效果:第三种与第二种一样
本文出自 “我爱大金子” 博客,请务必保留此出处http://1754966750.blog.51cto.com/7455444/1905537
以上是关于并发编程:锁重入与锁异常的主要内容,如果未能解决你的问题,请参考以下文章