`

java-锁 synchroinized & lock

 
阅读更多

线程安全问题:多线程对有状态可变的共享变量的修改,导至的问题。

需要使用锁来解决线程安全问题。

 

锁: 线程互斥性,内存可见性。

        线程互斥性:保证了对有状态可变的共享变量的顺序访问。

                 只有线程获得了锁才能对变量访问,线程释放锁之后,其它线程才能获得锁。

这是线程获得锁-》读写变量--》释放锁--下一个线程  --获得锁-》读写变量--》的过程 。

内存可见性: 进入获得锁后,变量从主内存读取,而不是缓存中读取,锁释放前,修改的变量写回主内存。

            下一条线程获得锁后,从主内存中取得的变量的有效数据。

 一、相同点

1.互斥性及可见性 

synchroinized:java 语法,可重入锁

   1.jvm控制线程互斥

   2.jvm控制内存可见性 (同步代码块中修改过的变量被写回主存)

  

 

 ReentrantLock : java类,可重入锁 

   1.使用Unsafe.park 或 Unsafe.unPack 阻塞线程或唤醒线程 ,控制线程的顺序执行。

   2.可见性保证:内部持有一个volatile 变量state:

           lock时,读state,让缓存失效,数据都从主内中读取。

           unlock时,写state,缓存中的数据写回主存。

   

2.都是可重入锁

3.支持非公平锁(ReentrantLock 支持非公平锁和公平锁,synchronized 是非公平锁。非公平锁性能比公平锁高一些)

 

二、不同点

1.写法

   a. synchronized 可以在静态方法,实例方法上,代码块上,不需要主机释放锁

       lock 代码块上,需要在 finally 里主动释放锁 lock.unlock()

2.公平性

       ReentrantLock 支持公平和非公平锁,synchronized 是非公平锁

3.锁等待及中断

      synchronized  :在锁被占用时,一直等待直到获得锁。--不支持中断

      Lock.lock() :在锁被占用时,一直等待直到获得锁。--不支持中断

      Lock.tryLock()  : 在锁被占用时,立即返回false.--不支持中断

      Lock.tryLock(long time, TimeUnit unit):在锁被占用时,等待指定时间,如果还未获得锁,则返回false

                                                                     --支持中断。

      Lock.lockInterruptibly()   : :在锁被占用时,一直等待直到获得锁.--支持中断

  

 4.锁定范围

       synchronized  :同一个监控器对象,可以是类实例,静态类。(内存地址相同的)

       Lock :同一个Lock实例

    

 

 

 

 

 

 

性能对比:

8个逻辑CPU,启用多个线程 从0开始+1 计数

竞争非常激烈:(锁内执行是时间约 0.05ms)  目标总值为:1000000000
16条线程:
使用synchronized:  use time:132秒 ,总值:1000000000,执行其间打印线程状态 :1条线程运行,15线程阻塞 java.lang.Thread.State: BLOCKED (on object monitor)
使用ReentrantLock: use time:39秒  ,总值:1000000000,执行其间打印线程状态 :1条线程运行,15线程阻塞 java.lang.Thread.State: WAITING (parking)
使用CAS自旋锁:     没有执行,原因:会执行很长时间,8个cpu 100%,怕把cpu烧坏了。


4条线程:
使用synchronized:  use time:139秒 ,总值:1000000000,执行其间打印线程状态 :4个cpu 70%左右,1条线程运行,3线程阻塞 java.lang.Thread.State: BLOCKED (on object monitor)
使用ReentrantLock: use time:43秒  ,总值:1000000000,执行其间打印线程状态 :4个cpu 40%左右,1条线程运行,3线程阻塞 java.lang.Thread.State: WAITING (parking)
使用CAS自旋锁:     use time:很长时间, 总值:1000000000,执行其间打印线程状态 :4个cpu 100%,    4条线程运行,

1条线程:
使用synchronized:  use time:29秒 , 总值:1000000000,执行其间打印线程状态 :1个cpu 100%,1条线程运行, 
使用ReentrantLock: use time:23秒  ,总值:1000000000,执行其间打印线程状态 :1个cpu 100%,1条线程运行,
使用CAS自旋锁:     use time:17秒  ,总值:1000000000,执行其间打印线程状态 :1个cpu 100%,1条线程运行,


竞争不激烈:(锁内代执行是时间约 0.05ms,锁内sleep(1ms),两个锁间sleep(1ms))  目标总值为:100000
4条线程:(相当于2线程抢一个锁)
使用synchronized:  use time:111秒  ,总值:100000,cpu非常低
使用ReentrantLock: use time:112秒  ,总值:100000,cpu非常低
使用CAS自旋锁:     use time:110秒  ,总值:100000,4个cpu 50%

16条线程:(相当于8个线程抢一个锁)
使用synchronized:  use time:112秒  ,总值:100000,cpu非常低
使用ReentrantLock: use time:112秒  ,总值:100000,cpu非常低
 


32条线程:(相当于16个线程抢一个锁)
使用synchronized:  use time:112秒  ,总值:100000,cpu非常低
使用ReentrantLock: use time:112秒  ,总值:100000,cpu非常低
 

256条线程:(相当于128个线程抢一个锁)
使用synchronized:  use time:112秒  ,总值:100000,cpu非常低
使用ReentrantLock: use time:112秒  ,总值:100000,cpu非常低

性能分析:
CAS自旋锁 :极少情况有竞争,锁内执行时间1ms以内--情况使用。要小心!
一般情况下,synchronized与ReentrantLock 性能相当。
在竞争极其激烈,线程极短时间内频繁阻塞唤醒,情况下使用ReentrantLock,性能好些。

 

 

分享到:
评论

相关推荐

    tua-body-scroll-lock::locked_with_key:身体滚动锁定功能适用于所有功能

    图阿身体滚动锁 受启发 English | 介绍 tua-body-scroll-lock启用所有内容的身体滚动锁定。 为什么不使用 ? 在Android Webview上不起作用 在带鼠标滚轮的PC上不起作用 如果您触摸某个地方而不是targetElement ,...

    AT89S52.rar_89s52_at89s52 isp_flash_operation

    &#8226 Three-level Program Memory Lock &#8226 256 x 8-bit Internal RAM &#8226 32 Programmable I/O Lines &#8226 Three 16-bit Timer/Counters &#8226 Eight Interrupt Sources &#8226 Full Duplex UART Serial...

    ATmega16A.rar_EEPROM_READ_avr_operation

    High-performance, Low-power Atmel AVR 8-bit Microcontroller &#1048698 Advanced RISC Architecture &#822 131 Powerful Instructions – Most Single-clock Cycle ...&#822 Programming Lock for Software Security

    java服务端开发合集-netty&并发&maven;

    Java提供了一套完整的并发工具库,包括线程、同步机制(如synchronized关键字和Lock接口)、并发集合(如ConcurrentHashMap)以及Future和ExecutorService等。理解和掌握如何有效地管理线程和资源,避免死锁、竞态...

    Core Java(Volume-Iⅈ--Fundamentals 9th Edition).rar

    1. **多线程编程**:讲解如何创建和管理线程,以及同步机制,如synchronized关键字和Lock接口。 2. **网络编程**:介绍套接字编程,包括TCP和UDP通信,以及Socket和ServerSocket类的使用。 3. **高级集合框架**:...

    advanced-java-master.zip

    本资源包"advanced-java-master.zip"主要涵盖了Java后端开发的高级主题,源自GitHub,旨在为开发者提供便捷的下载途径。这个压缩包中包含了一个完整的项目目录,让我们来逐一探讨其中可能涉及的知识点。 1. **Java...

    Python应用实战:python多线程-多线程安全问题&lock与rlock.zip

    本篇文章将深入探讨Python中的多线程安全问题以及如何使用锁(Lock)和可重入锁(RLock)来解决这些问题。 首先,我们要理解什么是线程安全。线程安全是指在多线程环境下,一个函数或方法被多个线程调用时,不会...

    Java-concurrency-master.zip

    2. **线程同步**:在多线程环境下,数据共享可能导致数据不一致问题,Java提供了多种同步机制,如`synchronized`关键字、`Lock`接口(包括`ReentrantLock`)以及`volatile`关键字,以确保线程安全。 3. **并发集合*...

    前端开源库-yarn-update-lock

    "yarn-update-lock"是一个针对前端开源库的实用工具,专注于管理和优化`yarn.lock`文件。这个工具的目的是确保项目依赖的版本是最新的,并且消除其中可能存在的重复项,从而保持项目的整洁和稳定。 `yarn.lock`文件...

    java的Lock锁原理详解.docx

    在Java中,有两种主要的锁机制:synchronized和Lock。它们都是用来实现线程同步,防止数据竞争,确保并发环境下的数据一致性。 首先,synchronized是Java的关键字,由JVM直接支持,其底层实现依赖于操作系统原语,...

    计算机后端-Java-Java核心基础-第20章 多线程 13. Lock锁方式解决线程安全问题.avi

    计算机后端-Java-Java核心基础-第20章 多线程 13. Lock锁方式解决线程安全问题.avi

    java-syn.zip_Java syn_Java syn锁_java同步锁syn_java锁 syn_syn同步事务锁

    - **显式锁**:如`java.util.concurrent.locks.Lock`接口及其实现,如`ReentrantLock`,提供了更复杂的锁操作,如可中断锁等待、公平锁等。 - **读写锁**:`ReentrantReadWriteLock`允许多个读取者同时访问,但...

    java面试题-java-interview-questions-master.zip

    1、 线程切换带来的原子性问题 解决办法:使用多线程之间同步synchronized或使用锁(lock)。 2、 缓存导致的可见性问题 解决办法:synchronized、volatile、LOCK,可以解决可见性问题 3、 编译优化带来的有序性问题...

    Redission分布式锁-本地单机Redis实战-springboot-redis-lock.zip

    4. **Redission实现分布式锁**:Redisson提供了RLock接口,它是Java Lock接口的实现,可以创建可重入的分布式锁。通过`RLock lock = redisson.getLock("myLock");`获取锁,然后`lock.lock();`锁定,`lock.unlock();`...

    java: xcb_xlib.c:50: xcb_xlib_unlock: Assertion `c->xlib.lock' failed

    当你在linux中安装eclipse或者安装其他的包时遇到这样得问题:java: xcb_xlib.c:50: xcb_xlib_unlock: Assertion `c->xlib.lock' failed,可以按照下面步骤:第一:倒退回FC7的libx11. 卸载以下两个包的时候,可能有...

    VS上位机工程COM&&LOCK.rar

    是一个基于Visual Studio(VS)开发的上位机项目,主要涉及LORA无线通信技术以及远程控制功能,尤其是针对电子锁的开关操作。LORA(Long Range)是一种低功耗、远距离的无线通信技术,常用于物联网(IoT)应用中,其...

    heroku-buildpack-ruby:Heroku的Ruby Buildpack

    用法Ruby用法示例: $ lsGemfile Gemfile.lock$ heroku create --buildpack heroku/ruby$ git push heroku main...-----> Heroku receiving push-----> Fetching custom buildpack-----> Ruby app detected...

    -------> RAFEL <------用WebPanel用Java编写的用于控制受害者的Android Rat-PHP开发

    即使应用程序已关闭(在某些设备上可能无法使用)辅助功能(在某些设备上导致Erros->忽略它)支持Android v5-v11否需要端口转发获取Wakelock完全无法检测到的旁路PlayProtect WipeSdcard锁定设备Scr

    heroku-buildpack-jekyll:用于 HerokuDokkuDeis 等的 Jekyll buildpack。从 https 分叉

    Gemfile Gemfile.lock $ heroku create --stack cedar --buildpack https://github.com/heroku/heroku-buildpack-ruby.git $ git push heroku master ... -----> Heroku receiving push -----> Fetching ...

    custom_buildpack

    Gemfile Gemfile.lock $ heroku create --buildpack heroku/ruby $ git push heroku main ... -----> Heroku receiving push -----> Fetching custom buildpack -----> Ruby app detected -----> ...

Global site tag (gtag.js) - Google Analytics