首页 > 试题广场 >

说说synchronize的用法及原理

[问答题]
说说synchronize的用法及原理
synchronized可以修饰静态方法、普通方法、代码块。 能够保证同一个时刻只有一个线程执行该段代码,保证线程安全。 在执行完或者出现异常时自动释放锁。 synchronized作用在代码块时,它的底层是通过monitorenter、monitorexit指令来实现的。
发表于 2022-04-26 16:07:43 回复(1)
一、用法:1. 静态方法上,则锁是当前类的Class对象。 2. 作用在普通方法上,则锁是当前的实例(this)。 3. 作用在代码块上,则需要在关键字后面的小括号里,显式指定一个对象作为锁对象。 能够保证同一个时刻只有一个线程执行该段代码,保证线程安全。 在执行完或者出现异常时自动释放锁。 二、原理:底层是采用Java对象头来存储锁信息的,并且还支持锁升级。在JVM里的实现都是 基于进入和退出Monitor对象来实现方法同步和代码块同步,
发表于 2022-05-01 18:09:03 回复(1)
用法:synchronize主要用于实现多线程对共享数据的互斥同步,其作用位置不同,加锁对象也就不同。作用于类或类中的静态方法时,加锁对象为类对象,作用于非静态方法时,加锁的对象类对象实例,作用位置为一个方法中的代码块时则为该类对象的部分代码加锁。 原理:在jvm的锁对象头中有一个markword用来记录锁对象的状态,分别有无锁,偏向锁,轻量级锁,重量级锁四种状态。最开始锁处于无锁状态,当第一个线程请求该锁并获得以后该锁的状态便变为偏向锁状态,并且线程对象会记录该锁表明当前获取到了该锁,在偏向锁状态中并不会有任何阻塞同步操作,甚至cas操作也不需要。直到有其它线程开始请求锁时,锁就会不再进入偏向锁状态。在后续中当一个线程请求到锁会先使用CAS操作来避免互斥同步带来的性能消耗直到CAS操作失败。这一时段内锁处于轻量级锁状态。失败后严格按照互斥同步处理,此时锁就处于重量级锁状态。
发表于 2022-05-11 15:03:14 回复(0)
用法:synchronized可以修饰普通方法,静态方法和同步代码块。 偏向锁原理:当线程第一次访问同步块并获取锁时,检测Mark Word是否为可偏向状态,即是否为偏向锁1,锁标识位为01为偏向锁,若为可偏向状态,则判断Mark word中的线程ID是否为当前线程ID,如果是,执行同步代码块,否则通过CAS操作将Mark Word的线程ID替换为当前线程ID,执行同步代码块。持有偏向锁的线程以后每次进入这个锁相关的同步块时,jvm都可以不再进行任何同步操作只需要判断id是否一致。偏向锁的效率高。 轻量级锁原理:1.判断当前对象是否处于无锁状态(hashcode、 0、01) , 如果是,则JVM首先将在当前线程的栈帧中建立-个名为锁记录(Lock Record)的空间,将对象的Mark Word复制到栈帧中的Lock Record中,将Lock Reocrd中的owner指向当前对象。2. JVM利用CAS操作尝试将对象的Mark Word存储指向Lock Record的指针,如果成功表示竞争到锁,则将锁标志位变成00变为轻量级锁,执行同步操作。3.如果失败则判断当前对象的Mark Word是否指向当前线程的栈帧,如果是则表示当前线程已经持有当前对象的锁,则直接执行同步代码块;否则只能说明该锁对象已经被其他线程抢占了,这时轻量级锁需要膨胀为重量级锁,锁标志位变成10,后面等待的线程将会进入阻塞状态。 重量级锁原理:当锁住一个线程时,会先去monitor对象中判断owner变量是否为空,为空就将owner存储当前线程以及通过cas将mark word存储指向monitor的指针指向当前monitor,然后当再有线程来时发现owner不为空将当前线程阻塞,并且放入entrylist集合中以链表的形式存储起来,当monitor中的owner置为null会释放掉该锁,然后entrylist里的线程被唤醒后,采用CAS去抢锁(这是不公平的,属于抢占式调度)重新竞争cpu的使用权。
编辑于 2023-05-16 14:06:37 回复(0)
用法:1、静态方法、普通方法、代码块;目的:保证同一个时刻只有一个进程执行这部分代码,保证线程安全。原理:使用Java对象头来存储锁信息,支持锁升级;1.6之后所分为无锁、偏向锁、轻量级锁、重量级锁。锁能升级不能降级;采用CAS + mark word 实现,mark word来存储锁信息。
发表于 2023-03-28 10:50:28 回复(0)
synchronized关键字可以用在三个地方,用在普通方法上,锁的对象是当前实例,用在静态方法上,锁的对象是class对象,用在代码块上,需要在后面指定一个显式对象作为锁.三种地方,对应不同锁的颗粒度,能保证被它修饰的方法或代码块,同一时间只有一个线程执行,并且保证资源的同步,可见性和原子性. 线程和进程都是CPU调度的,线程的执行,表示jvm里需要有这个线程的信息,而线程私有的空间为 虚拟机栈,本地方法栈,程序计数器,线程共有的空间有堆(类的信息)和方法区() 原理:synchronized底层是使用对象头来存储锁的信息,并且支持锁升级,对象头包括三部分分别是:Mark word(存储对象的hashcode及锁信息--锁的标注和锁的状态) /Class Metadata Address(存储对象类型的指针元空间数据?)/Array length存储数组对象的长度(不是数组则没有) java版本为了降低获取锁和释放锁的损耗,引入,无锁状态,偏向锁状态,轻量级锁状态,重量级锁状态,随线程竞争情况升级,锁状态逐步升级.synchronized引入偏向锁(偏向于某个线程,当一个线程访问同步块并获取锁时,会在对象头和栈帧中的锁记录里存储锁偏向的线程ID,以后该线程再进入和退出同步块时就不需要做加锁和解锁操作了,只需要简单地测试一下Mark Word里是否存储着自己的线程ID即可) 和 轻量级锁,就是加锁时JVM会在当前线程栈帧中创建用于存储锁的空间,并将Mark Word复制到锁记录中,然后线程尝试以CAS方式将Mark Word替换为指向锁记录的指针,如果成功,这当前线程获得锁,如果失败这表示其他线程竞争锁,此时,当前线程只会通过自璇来尝试获取锁. 锁升级过程
发表于 2023-02-10 10:26:14 回复(0)
1、synchronized加在三个不同的位置,对应三种不同的使用方式,这三种方式的区别是锁对象不同:
(1.)加在普通方法上,则锁是当前的实例(this)。
(2.)加在静态方法上,锁是当前类的Class对象。
(3.)加在代码块上,则需要在关键字后面的小括号里,显式指定一个对象作为锁对象。
2. synchronized是比较早期的API,在设计之初没有考虑到超时机制、非阻塞形式,以及多个条件变量。
3、Lock支持的功能包括:支持响应中断、支持超时机制、支持以非阻塞的方式获取锁、支持多个条件变量(阻塞队列)。
JDK的开发团队在1.5引入了Lock接口,并通过Lock支持了上述的功能。Lock支持的功能包括:支持响应中断、支持超时机制、支持以非阻塞的方式获取锁、支持多个条件变量(阻塞队列)。
synchronized采用“CAS+Mark Word”实现,为了性能的考虑,并通过锁升级机制降低锁的开销。
在并发环境中,synchronized会随着多线程竞争的加剧,按照如下步骤逐步升级:无锁、偏向锁、轻量级锁、重量级锁。
Lock则采用“CAS+volatile”实现,其实现的核心是AQS。
AQS是线程同步器,是一个线程同步的基础框架,它基于模板方法模式。
在具体的Lock实例中,锁的实现是通过继承AQS来实现的,并且可以根据锁的使用场景,派生出公平锁、不公平锁、读锁、写锁等具体的实现。
编辑于 2023-02-02 19:05:07 回复(0)
作用在静态方法上,表示锁定这个类,作用在普通方法上,表示锁定这个对象,作用在代码块时,在后面的小括号中需要显示指定需要对象
发表于 2022-09-18 15:47:08 回复(0)
原先:synchronized底层是靠对象头获取信息;关键字可以用在实例方法、静态方法、代码块,区别是加锁对象不同,synchronized可以自动释放锁,synchronized依赖Monitor。 之后: 添加: 底层是采用java对象头来存储锁信息(是“存储锁信息”)还支持锁升级。在jvm里的实现都是基于进入和推出Monitor对象来实现方法同步和代码块同步的。
发表于 2024-05-31 10:55:48 回复(0)
可以修饰静态方法(锁定类)、方法或者代码块(this)、变量。是一种同步机制,保证了指定代码段的串行操作。但是相比于Lock等锁也存在缺点,如效率低、不够灵活、无法得知是否成功获取锁等
发表于 2024-05-25 15:35:27 回复(0)
1.synchronized可以修饰静态方法、普遍方法、代码块 2.synchronized能够保证同一个时刻只有一个线程执行该段代码,保证线程安全,在执行完或者出现异常时自动释放锁,synchronized作用在代码块时,它的底层是通过monitorenter、monitorexit来实现的
发表于 2024-05-23 23:40:45 回复(0)
synchronized关键字修饰成员方法,静态方法和代码块,它能保证在任意时刻只能有一个线程访问该段代码,保证线程安全,在执行完或者出现异常时自动释放锁。synchronized修饰代码块使用的是monitorenter和monitorexit指令,monitorenter指向同步代码块的开始位置,monitorezit指向同步代码块的结束位置
发表于 2024-05-15 20:37:27 回复(0)
syn锁可以用在方法上,静态方法上 变量上 保证同时只有一个线程能进入代码块。执行完或者异常自动释放锁。 原理是对象头 对象头有3, markword 存储对象的hashcode和锁信息,metadata address 对象类型指针 arraylenth对象数组长度
编辑于 2024-04-02 16:12:39 回复(0)
1. 静态方法上,则锁是当前类的Class对象。 2. 作用在普通方法上,则锁是当前的实例对象。 3. 作用在代码块上,则需要在关键字后面的小括号里,显式指定一个对象作为锁对象。 能够保证同一个时刻只有一个线程执行该段代码,保证线程安全。 在执行完或者出现异常时自动释放锁。 二、原理:底层是采用Java对象头(MarkWord 1是偏向 0是非偏向)来存储锁信息的,并且还支持锁升级。在JVM里的实现都是 基于进入和退出Monitor对象来实现方法同步和代码块同步, 是非公平锁
编辑于 2024-04-01 17:49:18 回复(0)
答:synchronized可以修饰静态方法、普通方法、代码块。能够保证同一个时刻只有一个线程执行该段代码,保证线程安全。在执行完或者出现异常时自动释放锁。synchronized作用在代码块时,底层通过monitor enter以及monitor exit指令实现。
编辑于 2024-03-27 21:57:12 回复(0)
synchronized关键字 可用来修饰静态方法(锁定类对象)、普通方法(锁定this对象)、代码块(this对象) 能够保证同一时刻只有一个线程执行该段代码 ,保证线程安全 。 在执行完或发生异常时会自动释放锁 。 原理:通过对象头来存储锁信息的,基于进入Monitor或退出来实现方法的同步和代码块的同步
编辑于 2024-02-28 21:47:39 回复(0)
1. synchronize 有三种用户:普通方法(当前对象实例)、静态方法(当前类class对象)、代码块(指定小括号锁对象) 2. 原理:对象头存储锁信息,JVM提供两种指令实现方法同步和代码块同步 monitor enter/exit
编辑于 2024-02-22 17:34:43 回复(0)
用法: 同步方法: 在方法定义中使用synchronized关键字,可以确保整个方法在同一时间只能被一个线程执行。 public synchronized void synchronizedMethod() { // 同步的代码块 } 同步代码块: 使用synchronized关键字创建同步代码块,将需要同步的代码包裹在这个块内。通常,你需要提供一个锁对象(也称为监视器对象)来作为同步的依据。 public void someMethod() { // 非同步代码 synchronized (lockObject) { // 需要同步的代码 } // 非同步代码 } 原理: synchronized关键字的原理基于Java对象的内置锁机制(也称为监视器锁)。每个Java对象都有一个相关联的锁,当一个线程进入一个synchronized方法或代码块时,它会尝试获取这个对象的锁。如果锁已经被其他线程占用,线程将被阻塞,直到锁被释放。 以下是synchronized关键字的工作原理: 当一个线程尝试进入一个synchronized方法或代码块时,它会尝试获取对象的锁。 如果锁没有被其他线程占用,当前线程将获得锁,并执行关键部分。 如果锁已经被其他线程占用,当前线程将被阻塞,直到锁被释放。 一旦线程完成了关键部分的执行,它将释放锁,允许其他等待的线程竞争锁。 这个机制确保了在同一时间只有一个线程能够执行关键部分,从而保护了共享资源免受并发访问的干扰。 需要注意的是,synchronized方法或代码块的锁是与对象实例关联的,而不是与方法或代码块本身关联的。这意味着对于不同的对象实例,它们的synchronized方法或代码块可以并行执行,因为它们使用了不同的锁。
发表于 2023-09-25 11:02:35 回复(0)
先说用法: synchronized锁是互斥锁,能够保证同一时刻只有一个线程持有锁,可以修饰静态方法、普通方法和代码块; 修饰静态方法时,锁是当前类的Class对象;修饰普通方法时,锁是当前实例;修饰代码块时,需要在关键字后面的括号里显示的指定一个对象锁; 原理:源码在jvm中,底层是通过Java对象头存储锁信息,jdk1.6之后还支持锁升级;在jvm里的实现是基于monitor对象来实现方法同步和代码块同步的;monitor对象中有三个变量owner(存储当前持有锁线程的id)、entrylist(阻塞队列)、waitset(等待队列)
发表于 2023-08-23 10:52:54 回复(0)
synchronized可以修饰静态方法(锁加在类对象上),普通方法(锁加在类对象实例(this上)),代码块(关键字后面声明锁对象)。synchronized可以保证线程执行某段代码时其他线程不能执行,保证了线程安全。底层是采用java对象头来存储锁信息,基于monitor对象实习代码块和方法的同步
发表于 2023-08-11 15:47:36 回复(0)