synchronized:
用于同步方法或者代码块,使得多个线程在试图并发执行同一个代码块的时候,串行地执行。以达到线程安全的目的。
允许重入:
在多线程的时候是这样的,但是对于单线程,是允许重入的,每重入一次,计数器加1,当退出代码块时,计数器减1。
两次重入,在内层抛出异常:
那正常退出时计数器减1,抛异常时计数器也是减1。那如果两次重入,在内层抛出异常,会释放锁吗?还是只会计数器减1,锁并不会释放?
直接上代码验证:
public class SynchronizedTest1 { public static void main(String[] args){ Test test1 = new Test(); Thread thread1 = new Thread(test1); Thread thread2 = new Thread(test1); thread1.start(); thread2.start(); } } class Test implements Runnable{ public synchronized void hello() throws Exception{ System.out.println(Thread.currentThread().getName() + " say hello!!"); sorry(); System.out.println(Thread.currentThread().getName() + " helloed"); } public synchronized void sorry() throws Exception{ System.out.println(Thread.currentThread().getName() + " say sorry!!"); throw new Exception(Thread.currentThread().getName() + " this is a test!"); } public void run() { try { hello(); }catch (Exception e){ System.out.println(Thread.currentThread().getName() + " exception once"); } try { Thread.sleep(10000L); System.out.println(Thread.currentThread().getName() + " exit"); }catch (Exception e){ System.out.println(Thread.currentThread().getName() + " some exception"); } } }
Thread-0 say hello!! Thread-0 say sorry!! Thread-0 exception once Thread-1 say hello!! Thread-1 say sorry!! Thread-1 exception once Thread-1 exit Thread-0 exit Process finished with exit code 0
从以上运行结果,得出以下结论:
synchronized重入之后,内层抛出异常,跳出synchronized代码块,会释放锁。
题外话:一个很无聊的论点,结果显而易见,重点是有疑问时,写代码论证消除疑虑是最直接的方式。