深入分析JAVA Synchronized关键字

所属分类: 软件编程 / java 阅读数: 115
收藏 0 赞 0 分享

并发一致性的概念?

  是利用锁的机制来实现同步的,锁机制有如下两种特性:

    互斥性:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程中的协调机制,这样在同一时间只有一个线程对需同步的代码块(复合操作)进行访问。互斥性我们也往往称为操作的原子性。

    可见性:必须确保在锁被释放之前,对共享变量所做的修改,对于随后获得该锁的另一个线程是可见的(即在获得锁时应获得最新共享变量的值),否则另一个线程可能是在本地缓存的某个副本上继续操作从而引起不一致。

Synchronized的用法?

  1.同步方法

    同步非静态方法

/**
 * Synchronized关键字的用法
 * @author Administrator
 *
 */
public class SynchronizeDemo01 {

  /**
   * 修饰非静态方法
   * @Description: TODO
   * @returnType: void
   */
  public synchronized void accessResources1(){
    try {
      TimeUnit.SECONDS.sleep(2);
      System.out.println(Thread.currentThread().getName()+" is running!");
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  public static void main(String[] args) {

    //非静态方法的测试
    SynchronizeDemo01 demo01 = new SynchronizeDemo01();
    for (int i = 0; i < 5; i++) {
      new Thread(demo01::accessResources1).start();
    }

  }

}

     同步静态方法

/**
 * Synchronized关键字的用法
 * @author Administrator
 *
 */
public class SynchronizeDemo01 {
  /**
   * 修饰静态方法
   * @Description: TODO
   * @returnType: void
   */
  public synchronized static void accessResources0(){
    try {
      TimeUnit.SECONDS.sleep(2);
      System.out.println(Thread.currentThread().getName()+" is running!");
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  public static void main(String[] args) {
    //静态方法的测试
    for(int i=0;i<5;i++){
      new Thread(SynchronizeDemo01::accessResources0).start();
    }

  }

}

  2.同步代码块

    代码块对象,获取对象锁,在 Java 中,每个对象都会有一个 monitor 对象,这个对象其实就是 Java 对象的锁,通常会被称为“内置锁”或“对象锁”。类的对象可以有多个,所以每个对象有其独立的对象锁,互不干扰。

/**
 * Synchronized关键字的用法
 * @author Administrator
 *
 */
public class SynchronizeDemo01 {

  /**
   * synchronized代码块(对象),this指的是当前对象
   * @Description: TODO
   * @returnType: void
   */
  public void accessResources2(){
    synchronized(this){
      try {
        TimeUnit.SECONDS.sleep(2);
        System.out.println(Thread.currentThread().getName()+" is running!");
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }


  public static void main(String[] args) {
    //非静态方法的测试
    SynchronizeDemo01 demo01 = new SynchronizeDemo01();
    for (int i = 0; i < 5; i++) {
      new Thread(demo01::accessResources2).start();
    }

  }

}

    代码块 (类.class),获取类锁,在 Java 中,针对每个类也有一个锁,可以称为“类锁”,类锁实际上是通过对象锁实现的,即类的 Class 对象锁。每个类只有一个 Class 对象,所以每个类只有一个类锁。

/**
 * Synchronized关键字的用法
 * @author Administrator
 *
 */
public class SynchronizeDemo01 {

  /**
   * synchronized代码块(类.class)
   * @Description: TODO
   * @returnType: void
   */
  public void accessResources3(){
    synchronized(SynchronizeDemo01.class){
      //有Class对象的所有的对象都共同使用这一个锁
      try {
        TimeUnit.SECONDS.sleep(2);
        System.out.println(Thread.currentThread().getName()+" is running!");
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
  public static void main(String[] args) {
    //非静态方法的测试
    SynchronizeDemo01 demo01 = new SynchronizeDemo01();
    for (int i = 0; i < 5; i++) {
      new Thread(demo01::accessResources3).start();
    }

  }

}

Java对象的monitor对象的作用?

  1.当某一线程想要占有这个对象的时候,首先判断monitor 的计数器是不是0,如果是0表示还没有线程占有,这个时候线程可以占有这个对象,并且对这个对象的monitor+1;如果不为0,表示这个线程已经被其他线程占有,那么这个线程需要等待。当线程释放占有权的时候,monitor-1。

  2. 同一线程可以对同一对象进行多次加锁,+1,+1,重入性

Synchronized代码块的加锁机制?

  1.对代码块的加锁,通过反编译文件,发现在Monitorenter和Monitorexit中间是加锁的部分

  2.对方法的加锁,通过反编译文件,发现标有ACC_SYNCHRONIZED标识的为加锁方法

 Java虚拟机中几种锁的对比?

  无状态锁:没有加锁

  偏向锁:在对象第一次被某一线程占有的时候,会将“是否偏向锁”字段置为1,“锁标志位”记为01,写入线程号,当其他的线 程访问的时候,就会发生 竞争,如果竞争失败则升级为轻量级锁。偏向锁更加偏向第一次访问的线程获取锁成功。

     轻量级锁:线程有交替适用,互斥性不是很强,当偏向锁通过CAS算法获取锁失败,把锁标志位置为00。

  重量级锁:强互斥,锁标志位为10,等待时间长

以上就是深入分析JAVA Synchronized关键字的详细内容,更多关于JAVA Synchronized关键字的资料请关注脚本之家其它相关文章!

更多精彩内容其他人还在看

Java实现一个简单的文件上传案例示例代码

这篇文章主要介绍了Java实现一个简单的文件上传案例,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

详解在spring中使用JdbcTemplate操作数据库的几种方式

这篇文章主要介绍了详解在spring中使用JdbcTemplate操作数据库的几种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

java中的switch case语句使用详解

这篇文章主要介绍了java中的switch case语句使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

深入理解Java 线程池

这篇文章主要介绍了Java 线程池的相关资料,文中讲解非常细致,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

详解mybatis #{}和${}的区别、传参、基本语法

这篇文章主要介绍了mybatis #{}和${}的区别、传参、基本语法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

MyBatis 中 ${}和 #{}的正确使用方法(千万不要乱用)

这篇文章主要介绍了MyBatis 中 ${}和 #{}的正确使用方法,本文给大家提到了MyBatis 中 ${}和 #{}的区别,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

详解Mybatis中的 ${} 和 #{}区别与用法

这篇文章主要介绍了Mybatis中的 ${} 和 #{}区别与用法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Maven安装过程图文详解

这篇文章主要介绍了Maven安装过程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
收藏 0 赞 0 分享

SpringBoot登录拦截配置详解(实测可用)

这篇文章主要介绍了SpringBoot登录拦截配置详解(实测可用),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

JAVA 内存溢出案例汇总

这篇文章主要介绍了JAVA 内存溢出案例的汇总,文中讲解非常细致,帮助各位工作学习时避免内存溢出,感兴趣的朋友可以了解下
收藏 0 赞 0 分享
查看更多