深入分析JAVA Synchronized关键字

所属分类: 软件编程 / java 阅读数: 49
收藏 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 SpEL语法扫盲与查询手册的实现

这篇文章主要介绍了SpringBoot SpEL语法扫盲与查询手册的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Java创建子线程的两种方法

这篇文章主要介绍了Java创建子线程的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Spring Boot2.x集成JPA快速开发的示例代码

这篇文章主要介绍了Spring Boot2.x集成JPA快速开发,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

关于Java中的mysql时区问题详解

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

JAVA参数传递方式实例浅析【按值传递与引用传递区别】

这篇文章主要介绍了JAVA参数传递方式,结合实例形式分析了java按值传递与引用传递区别及相关操作注意事项,需要的朋友可以参考下
收藏 0 赞 0 分享

Java中MessageDigest来实现数据加密的方法

这篇文章主要介绍了Java中MessageDigest来实现数据加密的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

spring 注解验证@NotNull等使用方法

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

浅谈如何优雅地停止Spring Boot应用

这篇文章主要介绍了浅谈如何优雅地停止Spring Boot应用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Python如何使用@property @x.setter及@x.deleter

这篇文章主要介绍了Python如何使用@property @x.setter及@x.deleter,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Java Jmeter全局变量设置过程图解

这篇文章主要介绍了Java Jmeter全局变量设置过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多