java锁学习(二)

类锁

类锁 !!!! java类有很多对象 ,但是只有一个class对象 !!!!

所以,类锁,就是针对当前类的Class对象的锁

类锁同一时刻只能被一个对象获取

  1. synchronized放在static方法上(静态锁)
  2. 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对象运行完毕

常见场景和问题

  1. 两个线程同时访问一个对象的同步方法会怎样?

    依次执行(锁住的是同一个对象)

  2. 两个线程访问的是两个对象的同步方法又会怎样?

    随机执行(锁住的是不同的对象)

  3. 两个线程访问的是synchronized的静态方法会怎样?

    依次执行(锁住的是同一个类)

  4. 同时访问同步方法与非同步方法会怎样?

    只锁加了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运行结束

  5. 访问同一个对象的不同的普通同步方法会怎样?

    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运行结束

  6. 同时访问静态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运行结束

  7. 方法抛出异常后,会释放锁吗?

会,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

锁的使用场景及分析

整个系统全局同步用类锁,局部锁用对象锁

对比下,就像一样,锁的范围越大,性能自然越低(粒度:类锁>对象锁 性能:类锁<对象锁)

点赞
收藏

评论区

加载中...

相关推荐

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

notifyAll唤醒线程的范围?

今天看到开源中国上有这样一个问答:假设我有两个对象锁,对象A锁有5个线程在等待,对象B锁有3个线程在等待,对象A锁中的线程执行完,这时调用notifyAll,是唤醒了对象AB两个锁的全部的等待线程还是只唤醒了A锁的5个线程?1.方法文档解释通过看该方法文档的解释,可以得出下面结论:notifyAll()中All的含义是所有的线程,而不是所有的锁,只能唤

synchronize底层原理

1、普通同步方法,锁是当前实例对象2、静态同步方法,锁是当前类的class对象3、同步方法块,锁是括号里面的对象synchronize底层原理:Java虚拟机中的同步(Synchronization)基于进入和退出Monitor对象实现,无论是显式同步(有明确的monitorenter和monitorexit指令,即同步代

JAVA对象布局之对象头(Object Header)

由于Java面向对象的思想,在JVM中需要大量存储对象,存储时为了实现一些额外的功能,需要在对象中添加一些标记字段用于增强对象功能。在学习并发编程知识synchronized时,我们总是难以理解其实现原理,因为偏向锁、轻量级锁、重量级锁都涉及到对象头,所以了解java对象头是我们深入了解synchronized的前提条件,以下我们使用64

Java并发编程之Synchronized

引子目前在Java中存在两种锁机制:synchronized和Lock,今天我们先来介绍一下synchronizedsynchronized可以保证方法或代码块在运行时,同一时刻只有一个线程可以进入到临界区,同时它还保证了共享变量的内存可见性。用法Java中的每个对象都可以作为锁。每一个Object类及其子类

Java学习笔记7

lock接口实现类ReentrantLock我们可以用lock对象,来对临界资源加锁,只有获得lock对象才能访问临界资源,如果没有获得lock对象,就会进入lock对象的锁池。trylock()方法会返回布尔值,这个方法是用来判断这个锁对象是不是已经被线程获取,如果返回值为true,则会直接获得这个锁对象,如果返回false,线程不会阻塞还会继

java锁学习(二) - HelloWorld