深入分析JAVA Synchronized关键字

所属分类: 软件编程 / java 阅读数: 54
收藏 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关键字的资料请关注脚本之家其它相关文章!

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

SpringBoot中使用Ehcache的详细教程

EhCache 是一个纯 Java 的进程内缓存框架,具有快速、精干等特点,是 Hibernate 中默认的 CacheProvider。这篇文章主要介绍了SpringBoot中使用Ehcache的相关知识,需要的朋友可以参考下
收藏 0 赞 0 分享

在idea 中添加和删除模块Module操作

这篇文章主要介绍了在idea 中添加和删除模块Module操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

java spring整合junit操作(有详细的分析过程)

这篇文章主要介绍了java spring整合junit操作(有详细的分析过程),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

详解JAVA 弱引用

这篇文章主要介绍了 JAVA 弱引用的相关资料,帮助大家更好的理解和学习java引用对象,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

深入了解JAVA 虚引用

这篇文章主要介绍了JAVA 虚引用的相关资料,帮助大家更好的理解和学习JAVA,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

详解JAVA 强引用

这篇文章主要介绍了JAVA 强引用的相关资料,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

java中的按位与(&)用法说明

这篇文章主要介绍了java中的按位与(&)用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

深入了解JAVA 软引用

这篇文章主要介绍了JAVA 软引用的相关资料,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

利用MyBatis实现条件查询的方法汇总

这篇文章主要给大家介绍了关于利用MyBatis实现条件查询的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者使用MyBatis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
收藏 0 赞 0 分享

Intellij IDEA 与maven 版本不符 Unable to import maven project See logs for details: No implementation for org.apache.maven.model.path.PathTranslator was bound

这篇文章主要介绍了Intellij IDEA 与maven 版本不符 Unable to import maven project See logs for details: No implementation for org.apache.maven.model.path.Pa
收藏 0 赞 0 分享
查看更多