zoukankan      html  css  js  c++  java
  • java 对象锁学习

    机制

      锁机制是用来解决多线程共享资源时产生的冲突问题的。java 为每一个对象关联一个对象锁,通常把锁分为对象锁和类锁,他们的本质都是对象锁,只不过对象锁关联的是类的 Object 对象 (java.lang.Object),而类锁关联的是类的 Class 对象 java.lang.Class。
      jvm 对每个锁都有一个计数

    • 若该计数为 0,则锁没有被占用,可以被访问它的线程来持有
    • 一个对象的对象锁已被某个线程持有,新的线程来访问时将被挂起,知道持有它的线程释放该锁并且计数为 0
    • 一个线程已经持有了某个对象的锁,该线程再次访问该对象锁时可以重入,且计数 +1
    • 一个线程释放对象锁时,该锁的计数 -1,当某个锁的计数为 0 时锁被释放,可以被线程竞争

    分类

    • 不管怎么分类,java 中通过 synchronized 来实现的锁其本质都是对象锁
    • java 内部同步机制实现通常有两种方式,synchronized 修饰方法和语句块
    • synchronized 关键字作用于对象,这个对象可以是类的实例对象,也可以是 Class 对象

      • 类锁

      1 public class SyncObject {
      2     // 类锁1:通过static方法加同步锁
      3     public static synchronized void syncMethod1() {
      4         try {
      5             System.out.println("testMethod1 start!");
      6             Thread.sleep(3000);
      7         } catch (InterruptedException e) {
      8             e.printStackTrace();
      9         }
     10         System.out.println("testMethod1 end!");
     11     }
     12 
     13     public void syncMethod2() {
     14         // 类锁2:通过同步语句块传递Class类型参数
     15         synchronized (SyncObject.class) {
     16             try {
     17                 System.out.println("testMethod2 start!");
     18                 Thread.sleep(3000);
     19             } catch (InterruptedException e) {
     20                 e.printStackTrace();
     21             } finally {
     22                 System.out.println("testMethod2 end!");
     23             }
     24         }
     25     }
     26 }

    类锁作用于类的 Class 对象,对一个类来说,无论该类有多少个实例,它的静态变量和静态方法都只有一份,保存在 Class 对象中。通过对 Class 对象加锁来实现的同步语句或同步方法,无论该对象的哪个实例来访问,都需要竞争这个类锁

    •    对象锁

      1 public class SyncObject {
      2     // 对象锁1(方法锁):通过方法加同步锁
      3     public synchronized void syncMethod1() {
      4         try {
      5             System.out.println("testMethod1 start!");
      6             Thread.sleep(3000);
      7         } catch (InterruptedException e) {
      8             e.printStackTrace();
      9         }
     10         System.out.println("testMethod1 end!");
     11     }
     12 
     13     public void syncMethod2() {
     14         // 对象锁2:通过同步语句块传递Object类型参数
     15         synchronized (this) {
     16         // 此处的参数可以是本实例this,也可以是其它实例比如new SyncObject(),传入哪个实例就对哪个实例加锁
     17             try {
     18                 System.out.println("testMethod2 start!");
     19                 Thread.sleep(3000);
     20             } catch (InterruptedException e) {
     21                 e.printStackTrace();
     22             } finally {
     23                 System.out.println("testMethod2 end!");
     24             }
     25         }
     26     }
     27 }


    对象锁会对类的实例对象加锁,每一个 new 操作都会获得一个新的实例对象,对于 synchronized 修饰的非 static 方法或传递参数为实例对象的语句块,各个实例对象会拥有自己的锁。

    TIPS

      • synchronized 的作用范围是对象

        • synchronized 修饰的代码块需要传入一个对象参数(这个对象可以使 Class 对象),这个对象参数就是它的作用范围
        • synchronized 修饰的非静态方法的作用范围是 this,即当前对象实例。修饰静态方法时作用范围是这个类,即 Class 对象
      • synchronized 的粒度针不可再分


        因为锁是针对整个对象的,所以当某个对象的锁被持有后,其它线程不能持有该锁
        • 当一个线程调用某个对象 a 的 synchronized 方法(a.syncMethod1)在该方法结束之前,该对象的其它 synchronized 方法 (a.syncMethod2..) 都将不能被调用。同步代码块 synchronized(a)与 a.syncMethod1 有同样的作用周期
        • 当一个线程调用某个类 A 的 static synchronized 方法(A.staticSyncMethod1)在该方法结束前,该类的其它 static synchronized 方法(A.staticSyncMethod2..)都将不能被调用
        • 当一个线程调用某个对象 a 的 synchronized 方法(a.syncMethod1)在该方法结束之前,该类的其它 static synchronized 方法 (A.syncMethod2..) 还可以被调用,反之也成立
        • synchronized 的只对它修饰的模块加锁

          • 未被 synchronized 修饰的模块是可以被异步访问的, 因为线程访问它的时候并不需要获取对象锁
      • 相关阅读:
        Android 2.2 r1 API 中文文档系列(11) —— RadioButton
        Android API 中文 (15) —— GridView
        Android 中文 API (16) —— AnalogClock
        Android2.2 API 中文文档系列(7) —— ImageButton
        Android2.2 API 中文文档系列(6) —— ImageView
        Android 2.2 r1 API 中文文档系列(12) —— Button
        Android2.2 API 中文文档系列(8) —— QuickContactBadge
        [Android1.5]TextView跑马灯效果
        [Android1.5]ActivityManager: [1] Killed am start n
        Android API 中文(14) —— ViewStub
      • 原文地址:https://www.cnblogs.com/ios9/p/7473165.html
      Copyright © 2011-2022 走看看