首页 > 其他分享 >synchronized 关键字 - 监视器monitor lock

synchronized 关键字 - 监视器monitor lock

时间:2024-03-28 21:03:47浏览次数:14  
标签:加锁 monitor synchronized lock 线程 修饰 SynchronizedDemo public

目录

1.synchronized的特性

1.1互斥

1.2可重入

2.synchronized 使用示例

2.1修饰代码块:明确指定锁那个对象

2.2直接修饰普通方法:锁的SynchronizedDemo 对象

2.3修饰静态方法:锁的SynchronizedDemo 类的对象

3.Java标准库中的线程安全类


1.synchronized的特性

1.1互斥

synchronized会起到互斥效果,某个线程执行到某个对象的synchronized中时,其他线程如果也执行到同一个对象synchronized就会阻塞等待。

  • 进入synchronized 修饰的代码块,相当于加锁。
  • 退出synchronized 修饰的代码块,相当于解锁。

 synchronized用的锁是存在java对象头里的。

一个线程先上了锁,其他的线程只能等待这个线程释放

理解“阻塞等待”

针对每一把锁,操作系统内部都维护了一个等待队列,当这个锁被某一个线程占有的时候,其他线尝试进行加锁,就加不上了,就会阻塞等待,一直等到之前的线程解锁之后,由操作系统唤醒一个新的线程,再来获取到这个锁。

注意:

  • 上一个线程解锁之后,下一个线程并不是立即就能获取到锁,而是要靠操作系统来唤醒,这也就是操作系统线程调度的一部分工作。
  • 假设由ABC三个线程,线程A先获取到锁,然后B尝试获取锁,然后C再尝试获取锁,此时B和C都在阻塞队列中排队等待,但是当A释放锁之后,虽然B比C先来的,但是B不一定就能获取到锁,而且都是和C重新竞争,并不遵守先来后到的规则。

synchronized的底层是使用操作系统的mutex lock实现的。

1.2可重入

synchronized 同步对同一条线程来说是可重入的,不会出现自己把自己锁死的问题;

理解“把自己锁死”

一个线程没有释放锁,然后又尝试再次加锁。

第一次加锁,加锁成功。

lock();

第二次加锁,所已经被占用,阻塞等待。

lock();

按照之前对于锁的设定,第二次加锁的时候,就会阻塞等待,直到第一次的锁被释放,才能获取到第二次锁,但是释放第一个锁也是由该线程来完成的,结果这个线程已经躺平了,也就无法进行解锁操作,这时候就会死锁。

java中的synchronized 是可重入锁,因此没有上面问题。

for (int i = 0; i < 50000; i++) {
 synchronized (locker) {
 synchronized (locker) {
 count++;
 }
 }
}

在可重入锁的内部,包含了“线程持有者”和“计数器”两个信息。

  • 如果某个线程加锁的时候,发现锁已经被人占用,但是恰好占用的是自己,那么仍然可以继续获取到锁,并上计数器自增。
  • 解锁的时候计数器递减为0,才真正释放锁(才能被别的线程获取到)。

2.synchronized 使用示例

2.1修饰代码块:明确指定锁那个对象

锁任意对象

public class SynchronizedDemo {
 private Object locker = new Object();
 
 public void method() {
 synchronized (locker) {
 
 }
 }
}

锁当前对象

public class SynchronizedDemo {
 public void method() {
 synchronized (this) {
}
}
}
2.2直接修饰普通方法:锁的SynchronizedDemo 对象
public class SynchronizedDemo {
 public synchronized void methond() {
 }
}
2.3修饰静态方法:锁的SynchronizedDemo 类的对象
public class SynchronizedDemo {
 public synchronized static void method() {
 }
}

我们重点理解,synchronized锁是什么。两个线程竞争同一把锁,才会产生阻塞等待。

两个线程分别尝试获取两把不同的锁,不会产生竞争。 

3.Java标准库中的线程安全类

java标准库中很多都是线程不安全的,这些类可能会涉及到多线程修改共享数据有没,又没有

任何加锁措施。

ArrayList

LinkedList

HashMap

TreeMap

HashSet

TreeSet

StringBuilder

但是还是有一些线程是安全的,使用了一些锁机制控制。

Vector    HashTable    ConcurrHashMap  StringBuffer

StringBuffer的核心方法都带有synchronized。

还有的虽然没有加锁,但是不涉及“修改”,仍然线程是安全的。

标签:加锁,monitor,synchronized,lock,线程,修饰,SynchronizedDemo,public
From: https://blog.csdn.net/2301_79719531/article/details/137092217

相关文章

  • msg="Sync \"monitoring/main\" failed: provision alertmanager configuration: ba
    今天在调整k8s监控的时候有个搞错这里做个记录以及处理方法level=infots=2024-03-28T08:30:21.320852843Zcaller=operator.go:742component=alertmanageroperatorkey=monitoring/mainmsg="syncalertmanager"level=errorts=2024-03-28T08:30:21.324600111Zcaller=klo......
  • KingbaseES LWLock buffer_mapping 等待
    在KingbaseES数据库中,会话在将数据块与共享缓冲池的缓冲区相关联时,会触发“LWLockbuffer_mapping”等待事件。这类事件涉及到一种轻量级锁(lwlock),类似于Oracle中的闩锁。这个锁在不同的数据库中可能有不同的名称,但通常被称为buffer_mapping或BufMappingLock。它主要用于实现对HAS......
  • TextBlock 的run元素
    这里第一个run的content滚滚长江东逝水,浪花淘尽英雄。是非成败转头空。青山依旧在,几度夕阳红。和第二个的Text有什么区别?<TextBlockx:Name="textblock"Width="320"Height="100"FontSize="......
  • openGauss Xlog-no-Lock-Flush
    XlognoLockFlush可获得性本特性自openGauss2.0.0版本开始引入。特性简介取消WalInsertLock争抢及WalWriter专用磁盘写入线程。客户价值在保持原有XLog功能不变的基础上,进一步提升系统性能。特性描述对WalInsertLock进行优化,利用LSN(LogSequenceNumber)及LRC(LogRecor......
  • Yolov8-pose关键点检测:block涨点篇 | PKIBlock多尺度卷积核,优势无需膨胀,即插即用小目
      ......
  • hdu1195 Open the Lock
    双向广搜的没写,这个是普通bfs,哪天改一下……#include<iostream>#include<algorithm>#include<string>#include<queue>#include<cstring>usingnamespacestd;intT,vis[10000];stringst,en;intdir[2]={-1,1};typedefstruct{ stringa;......
  • ReentrantLock 原理
    (一)、非公平锁实现原理1、加锁解锁流程先从构造器开始看,默认为非公平锁实现publicReentrantLock(){sync=newNonfairSync();}NonfairSync继承自AQS没有竞争时加锁流程构造器构造,默认构造非公平锁(无竞争,第一个线程尝试加锁时)加锁,luck(),finalvoidlo......
  • sychronized和ReentrantLock对比
    共同点①都用于多线程对共享对象的访问。②都是可重入锁。③都保证了可见性和互斥性。不同点①ReentrantLock显示获取和释放锁;synchronized隐式获取和释放锁。②Reentrant可响应中断、可轮询,为处理锁提供了更强的灵活性。③ReentrantLock是API级别的,synchronized是JVM级......
  • ReentrantLock重入锁
    ​一,重入锁定义重入锁,顾名思义,就是支持重新进入的锁,表示这个锁能够支持一个线程对资源重复加锁。如果一个线程已经拿到了锁,那么他需要再次获取锁的时候不会被该锁阻塞。举个例子,publicsynchronizedvoidtest(){dosomething...test2();}publicsynchronizedvoid......
  • BitLocker和EFS(Encrypting File System)是Windows操作系统中用于数据加密的两种不同的
    BitLocker和EFS(EncryptingFileSystem)是Windows操作系统中用于数据加密的两种不同的功能。BitLocker:BitLocker是一种全磁盘加密技术,它可以加密整个硬盘驱动器上的数据,包括操作系统、应用程序和用户数据等。BitLocker可以保护计算机在启动时的数据安全,并且可以通过预启动认......