资讯专栏INFORMATION COLUMN

synchronized基本使用以及原理

FullStackDeveloper / 1511人阅读

摘要:场景在并发编程中存在线程安全问题,主要原因有存在共享数据,多线程共同操作共享数据。底层语义原理可通过工具和去观察的底层以及线程情况。注同一个线程可以对同一个对象多次加锁,,,重入锁

1. 场景

      在并发编程中存在线程安全问题,主要原因有:存在共享数据,多线程共同操作共享数据。关键字synchronized可以保证在同一时刻,只有一个线程可以执行某个方法或某个代码块,同时synchronized可以保证一个线程的可见性

2. 概念

利用锁的机制来实现同步的(解决数据点不一致性 JMM)

锁机制有如下两种特性

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

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

3. synchronized的用法

同步方法(分普通方法和静态方法)
用法:只需要在方法上面添加synchronized关键字即可。
同步普通方法:只能作用在单例上面,如果不是单例,同步方法锁将失效。
同步静态方法:不管你有多少个类实例,同时只有一个线程能获取锁进入这个方法。

同步对象实例

 private static int m = 0;
 private Object obj = new Object();

 public void test1() {
     try {
         synchronized (obj) {
             TimeUnit.MINUTES.sleep(2);
             m++;
         }
     } catch (InterruptedException e) {
         e.printStackTrace();
     }
 }

同步类

锁效果与同步静态方法一样,都是类级别的锁,同时只有一个线程能访问带有同步类锁的方法。

public class synchronizedDemo {
    private static int m = 0;
    public void test2() {
        try {
            synchronized (synchronizedDemo.class) {
                TimeUnit.MINUTES.sleep(2);
                m++;
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

同步this实例

与同步块的用法一致,表示锁住整个当前对象实例,只有获取到这个实例的锁才能进入这个方法。

private static int m = 0;
    public void test2() {
        try {
            synchronized (this) {
                TimeUnit.MINUTES.sleep(2);
                m++;
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
4. synchronized底层语义原理

可通过工具jconsole和jstack去观察synchronized的底层以及线程情况。

方法锁:

方法锁就是由关键字ACC_SYNCHRONIZED实现是否互斥方法,

对象锁:

monitor:在jvm规范中每个对象和类在逻辑上都是和一个监视器(monitor)相关联的,为了实现监视器的排他性监视能力,JVM为每一个对象和类都关联一个锁,锁住了一个对象,这就是获得对象相关联的监视器。
实现原理:某一个线程占有这个对象的时候,首先monitor的计数器是不是0,如果是0表示还没有线程占有这个时候线程占有这个对象,并且对这个对象的monitor+1;如果不为0表示这个对象已经被其他线程占有,这个线程等待。当线程释放占有权的时候monitor-1。
注:同一个线程可以对同一个对象多次加锁,+1,+1,重入锁

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75905.html

相关文章

  • java篇

    摘要:多线程编程这篇文章分析了多线程的优缺点,如何创建多线程,分享了线程安全和线程通信线程池等等一些知识。 中间件技术入门教程 中间件技术入门教程,本博客介绍了 ESB、MQ、JMS 的一些知识... SpringBoot 多数据源 SpringBoot 使用主从数据源 简易的后台管理权限设计 从零开始搭建自己权限管理框架 Docker 多步构建更小的 Java 镜像 Docker Jav...

    honhon 评论0 收藏0
  • Java 中的 Monitor 机制

    摘要:基本元素机制需要几个元素来配合,分别是临界区对象及锁条件变量以及定义在对象上的,操作。这个外部条件在机制中称为条件变量。提供的机制,其实是,等元素合作形成的,甚至说外部的条件变量也是个组成部分。 monitor的概念 管程,英文是 Monitor,也常被翻译为监视器,monitor 不管是翻译为管程还是监视器,都是比较晦涩的,通过翻译后的中文,并无法对 monitor 达到一个直观的描...

    Jacendfeng 评论0 收藏0
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTran

    摘要:使用可以禁止的指令重排,保证在多线程环境下也能正常运行。关键字底层原理总结关键字底层原理属于层面。另外在中引入了自适应的自旋锁。自适应的自旋锁带来的改进就是自旋的时间不在固定了,而是和前一次同一个锁上的自旋时间以及锁的拥有者 【强烈推荐!非广告!】阿里云双11褥羊毛活动:https://m.aliyun.com/act/team1111/#/share?params=N.FF7yxCc...

    Vixb 评论0 收藏0
  • Java面试题

    摘要:近段时间在准备实习的面试,在网上看到一份面试题,就慢慢试着做,争取每天积累一点点。现在每天给自己在面试题编写的任务是题,有时候忙起来可能就没有时间写了,但是争取日更,即使当天没更也会在之后的更新补上。     近段时间在准备实习的面试,在网上看到一份面试题,就慢慢试着做,争取每天积累一点点。    暂时手头上的面试题只有一份,题量还是挺大的,有208题,所以可能讲的不是很详细,只是我自...

    OnlyMyRailgun 评论0 收藏0
  • BATJ都爱问的多线程面试题

    摘要:今天给大家总结一下,面试中出镜率很高的几个多线程面试题,希望对大家学习和面试都能有所帮助。指令重排在单线程环境下不会出先问题,但是在多线程环境下会导致一个线程获得还没有初始化的实例。使用可以禁止的指令重排,保证在多线程环境下也能正常运行。 下面最近发的一些并发编程的文章汇总,通过阅读这些文章大家再看大厂面试中的并发编程问题就没有那么头疼了。今天给大家总结一下,面试中出镜率很高的几个多线...

    高胜山 评论0 收藏0

发表评论

0条评论

FullStackDeveloper

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<