synchronized基本使用以及原理

光明磊落
• 阅读 2069

1. 场景

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

2. 概念

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

  • 锁机制有如下两种特性
  1. 互斥性
    在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程中的协调机制,这样在同一时间只有一个线程对所需同步的代码块(复合操作)进行访问。互斥性也称为操作的原子性
  2. 可见性
    必须确保在锁被释放之前,对共享变量所做的修改,对于随后获得该锁的另一个线程是可见的(即在获得锁时应获得最新共享变量的值),否则另一个线程可能是在本地缓存的某个副本上继续操作从而引起不一致。

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,重入锁

点赞
收藏
评论区
推荐文章
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
java锁学习(一)
作用能够保证同一时刻,最多只有一个线程执行该段代码,以达到并发安全的效果主要用于同时刻对线程间对任务进行锁地位synchronized是JAVA的原生关键字,是JAVA中最基本的互斥手段,是并发编程中的元老角色不使用并发的后果不使用并发会导致多线程情况下,同一个数据被多个线程同时更改,造成结果和预期不一致
Wesley13 Wesley13
4年前
java 面试知识点笔记(十)多线程与并发
问:线程安全问题的主要诱因?1.存在共享数据(也称临界资源)2.存在多条线程共同操作这些共享数据解决方法:同一时刻有且只有一个线程在操作共享数据,其他线程必须等到该线程处理完数据后再对共享数据进行操作互斥锁的特征:1.互斥性:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程协调机制,这样在同一时间只有一
Stella981 Stella981
4年前
Redis的锁
分布式与集群什么是锁在单进程的系统中,当存在多个线程可以同时改变某个变量(可变共享变量)时,就需要对变量或代码块做同步,使其在修改这种变量时能够线性执行消除并发修改变量。而同步的本质是通过锁来实现的。为了实现多个线程在一个时刻同一个代码块只能有一个线程可执行,那么需要在某个地方做个标记,这个标记必须
Wesley13 Wesley13
4年前
Java并发编程之Synchronized
引子目前在Java中存在两种锁机制:synchronized和Lock,今天我们先来介绍一下synchronizedsynchronized可以保证方法或代码块在运行时,同一时刻只有一个线程可以进入到临界区,同时它还保证了共享变量的内存可见性。用法Java中的每个对象都可以作为锁。每一个Object类及其子类
Wesley13 Wesley13
4年前
Java 之 synchronized 详解
一、概念synchronized是Java中的关键字,是利用锁的机制来实现同步的。锁机制有如下两种特性:互斥性:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程中的协调机制,这样在同一时间只有一个线程对需同步的代码块(复合操作)进行访问。互斥性我们也往往称为操作的原子性。可见性:必须确
Wesley13 Wesley13
4年前
Java多线程synchronized关键字引出的多种锁
前言Java中的 synchronized关键字可以在多线程环境下用来作为线程安全的同步锁。本文不讨论 synchronized 的具体使用,而是研究下synchronized底层的锁机制,以及这些锁分别的优缺点。一、synchronized机制synchro
Wesley13 Wesley13
4年前
Java多线程(二)
\恢复内容开始一,volatile关键字当多个线程操作共享数据时,可以保证内存中的数据可见性相较于synchronized关键字:1,不具备“互斥性”2,不能保证变量的原子性二,原子变量volatile保证内存可见性CAS(CompareAndSwap)算法保证数据的原子性内存值V预估值A更新值
Wesley13 Wesley13
4年前
Java分布式锁看这篇就够了
\什么是锁?在单进程的系统中,当存在多个线程可以同时改变某个变量(可变共享变量)时,就需要对变量或代码块做同步,使其在修改这种变量时能够线性执行消除并发修改变量。而同步的本质是通过锁来实现的。为了实现多个线程在一个时刻同一个代码块只能有一个线程可执行,那么需要在某个地方做个标记,这个标记必须每个线程都能看到
深入理解分布式锁:原理、应用与挑战| 京东物流技术团队
前言在单机环境中,我们主要通过线程间的加锁机制来确保同一时间只有一个线程能够访问某个共享资源或执行某个关键代码块,从而防止各种并发修改异常。例如,在Java中提供了synchronized/Lock。但是在分布式环境中,这种线程间的锁机制已经不起作用了,因
京东云开发者 京东云开发者
11个月前
深入理解分布式锁:原理、应用与挑战
作者:京东物流刘浩前言在单机环境中,我们主要通过线程间的加锁机制来确保同一时间只有一个线程能够访问某个共享资源或执行某个关键代码块,从而防止各种并发修改异常。例如,在Java中提供了synchronized/Lock。但是在分布式环境中,这种线程间的锁机制
光明磊落
光明磊落
Lv1
我的世界,我一个人懂就好。
文章
3
粉丝
0
获赞
0