类锁
类锁 !!!! java类有很多对象 ,但是只有一个class对象 !!!!
所以,类锁,就是针对当前类的Class对象的锁
类锁同一时刻只能被一个对象获取
- synchronized放在static方法上(静态锁)
- synchronized放在class对象上
静态锁
1class SyncClassStatic implements Runnable { 2 @Override 3 public void run() { 4 method(); 5 } 6 7 public static synchronized void method() { 8 System.out.println("我是类锁中静态锁"); 9 try{ 10 Thread.sleep(3000); 11 }catch (InterruptedException e) { 12 e.printStackTrace(); 13 } 14 15 System.out.println(Thread.currentThread().getName()+"运行结束"); 16 } 17} 18result: 19我是类锁中静态锁 20Thread-6运行结束 21我是类锁中静态锁 22Thread-7运行结束 23类锁,静态锁运行完毕
class对象锁
1class SyncClassObj implements Runnable{ 2 @Override 3 public void run() { 4 method(); 5 } 6 7 private void method(){ 8 synchronized (SyncClassObj.class) { 9 System.out.println("我是类锁中class对象锁"); 10 try{ 11 Thread.sleep(3000); 12 }catch (InterruptedException e) { 13 e.printStackTrace(); 14 } 15 16 System.out.println(Thread.currentThread().getName()+"运行结束"); 17 } 18 } 19} 20result: 21我是类锁中class对象锁 22Thread-8运行结束 23我是类锁中class对象锁 24Thread-9运行结束 25类锁,class对象运行完毕
常见场景和问题
-
两个线程同时访问一个对象的同步方法会怎样?
依次执行(锁住的是同一个对象)
-
两个线程访问的是两个对象的同步方法又会怎样?
随机执行(锁住的是不同的对象)
-
两个线程访问的是synchronized的静态方法会怎样?
依次执行(锁住的是同一个类)
-
同时访问同步方法与非同步方法会怎样?
只锁加了synchronized的方法,其他方法不会收到影响
class SyncObjLock implements Runnable {
1@Override 2public void run() { 3 if(Thread.currentThread().getName().equals("Thread-0")) { 4 syncMethod(); 5 }else{ 6 asyncMethod(); 7 } 8} 9 10private synchronized void syncMethod() 11{ 12 System.out.println("我被锁了"); 13 try{ 14 Thread.sleep(3000); 15 }catch (InterruptedException e) { 16 e.printStackTrace(); 17 } 18 19 System.out.println(Thread.currentThread().getName()+"运行结束"); 20} 21 22private void asyncMethod() 23{ 24 System.out.println("我没被锁"); 25 try{ 26 Thread.sleep(3000); 27 }catch (InterruptedException e) { 28 e.printStackTrace(); 29 } 30 31 System.out.println(Thread.currentThread().getName()+"运行结束"); 32}} 同时开始,同时结束: 我被锁了 我没被锁 Thread-0运行结束 Thread-1运行结束
-
访问同一个对象的不同的普通同步方法会怎样?
class SyncDiff implements Runnable{ @Override public void run() { if(Thread.currentThread().getName().equals("Thread-0")) { syncMethod1(); }else{ syncMethod2(); } }
1private synchronized void syncMethod1() 2{ 3 System.out.println("我被锁了,我是方法1"); 4 try{ 5 Thread.sleep(3000); 6 }catch (InterruptedException e) { 7 e.printStackTrace(); 8 } 9 10 System.out.println(Thread.currentThread().getName()+"运行结束"); 11} 12 13 14private synchronized void syncMethod2() 15{ 16 System.out.println("我被锁了,我是方法2"); 17 try{ 18 Thread.sleep(3000); 19 }catch (InterruptedException e) { 20 e.printStackTrace(); 21 } 22 23 System.out.println(Thread.currentThread().getName()+"运行结束"); 24}} 同时开始,同时结束: 我被锁了 我没被锁 Thread-0运行结束 Thread-1运行结束
-
同时访问静态sync和非静态sync方法
class SyncStaticOrNo implements Runnable { @Override public void run() { if(Thread.currentThread().getName().equals("Thread-0")) { syncMethod1(); }else{ syncMethod2(); } }
1private synchronized void syncMethod1() 2{ 3 System.out.println("我被对象锁"); 4 try{ 5 Thread.sleep(3000); 6 }catch (InterruptedException e) { 7 e.printStackTrace(); 8 } 9 10 System.out.println(Thread.currentThread().getName()+"运行结束"); 11} 12 13 14private static synchronized void syncMethod2() 15{ 16 System.out.println("我是类锁"); 17 try{ 18 Thread.sleep(3000); 19 }catch (InterruptedException e) { 20 e.printStackTrace(); 21 } 22 23 System.out.println(Thread.currentThread().getName()+"运行结束"); 24}} 同时开始,同时结束: 我被锁了 我没被锁 Thread-0运行结束 Thread-1运行结束
-
方法抛出异常后,会释放锁吗?
会,jvm帮我们释放了
1class SyncExc implements Runnable{ 2 3 4 @Override 5 public void run() { 6 method1(); 7 } 8 9 private synchronized void method1() 10 { 11 System.out.println(Thread.currentThread().getName()+"开始"); 12 try{ 13 Thread.sleep(3000); 14 }catch (Exception e) { 15 e.printStackTrace(); 16 } 17 throw new RuntimeException(""); 18// System.out.println("运行结束"); 19 } 20 21} 22 23 24Thread-0开始 25Exception in thread "Thread-0" java.lang.RuntimeException: 26 at Thread.SyncExc.method1(SynchronizedObject.java:187) 27 at Thread.SyncExc.run(SynchronizedObject.java:176) 28 at java.lang.Thread.run(Thread.java:748) 29Thread-1开始 30Exception in thread "Thread-1" java.lang.RuntimeException: 31 at Thread.SyncExc.method1(SynchronizedObject.java:187) 32 at Thread.SyncExc.run(SynchronizedObject.java:176) 33 at java.lang.Thread.run(Thread.java:748) 34
锁的使用场景及分析
整个系统全局同步用类锁,局部锁用对象锁
对比下,就像一样,锁的范围越大,性能自然越低(粒度:类锁>对象锁 性能:类锁<对象锁)