java 关键字 volatile、synchronized、Lock

news/2024/5/17 15:21:52 标签: volatile, synchronized, Lock, 同步锁

volatile

简介:
    用以声明变量的值可能随时会别的线程修改
    使用volatile修饰的变量会强制将修改的值立即写入主存
    主存中值的更新会使缓存中的值失效
    
特性:
    1. 可见性
        当多个线程访问同一个变量时,某一个线程修改了变量的值,其他线程能够立即读取到该变量修改后的值。
    2. 有序性
        即程序执行时按照代码书写的先后顺序执行。
        在Java内存模型中,允许编译器和处理器对指令进行重排序,
        但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。
    3. 不具有原子性
        原子性:
            即事务执行不完全会发生事务回滚,恢复初始状态。

注意:
    volatile不会让线程阻塞,响应速度比synchronized高,这是它的优点。
    

synchronized 同步锁

功能:
    1. 修饰代码块:
        被修饰的代码块称为同步语句块,
        其作用的范围是大括号{}括起来的代码,
        作用的对象是调用这个代码块的对象
        一个线程访问一个对象中的synchronized(this)同步代码块时,
        其他试图访问该对象的线程将被阻塞。
        说明:
            当两个并发线程(thread1和thread2)访问同一个对象(syncThread)中的synchronized代码块时,
            在同一时刻只能有一个线程得到执行,另一个线程受阻塞,必须等待当前线程执行完这个代码块以后才能执行该代码块。
            Thread1和thread2是互斥的,因为在执行synchronized代码块时会锁定当前的对象,
            只有执行完该代码块才能释放该对象锁,下一个线程才能执行并锁定该对象。
            每通过new关键字创建一个对象都是不同的对象,不能称作同一对象。
            
    2. 修饰方:
        被修饰的方法称为同步方法,
        其作用的范围是整个方法,
        作用的对象是调用这个方法的对象
        当一个线程访问对象的一个synchronized(this)同步代码块时,
        另一个线程仍然可以访问该对象中的非synchronized(this)同步代码块。
        说明:
            countAdd是一个synchronized的,printCount是非synchronized的。
            一个线程访问一个对象的synchronized代码块时,别的线程可以访问该对象的非synchronized代码块而不受阻塞。
        
    3. 修饰静态的方法:
        其作用的范围是整个静态方法,
        作用的对象是这个类的所有对象
        synchronized修饰方法和修饰一个代码块类似,只是作用范围不一样,
        修饰代码块是大括号括起来的范围,而修饰方法范围是整个函数。
        静态方法是属于类的而不属于对象的。
        synchronized修饰的静态方法锁定的是这个类的所有对象。
        说明:
            两种写法:
                1. public synchronized void method () {}
                2. public void method () {
                        synchronized (this) {}
                    }
        注意:
            1. synchronized关键字不能继承。
            2. 在定义接口方法时不能使用synchronized关键字。
            3. 构造方法不能使用synchronized关键字,但可以使用synchronized代码块来进行同步
            
        
    4. 修饰类:
        其作用的范围是synchronized后面括号括起来的部分,
        作用主的对象是这个类的所有对象
        synchronized作用于一个类T时,
        是给这个类T加锁,T的所有对象用的是同一把锁。


Lock

1. 通过Lock可以知道线程有没有成功获取到锁。synchronized无法办到的。

2. Lock不是Java语言内置的,synchronized是Java语言的关键字,因此是内置特性。
    Lock是一个类,通过这个类可以实现同步访问

3. synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,
    而且在代码执行时出现异常,JVM会自动释放锁定,
    但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中

4. 在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetrantLock
    但是在资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,
    
lock的四个取锁方法:
    lock()
        就是用来获取锁。如果锁已被其他线程获取,则进行等待。
    tryLock()
        有返回值,表示用来尝试获取锁,如果获取成功,则返回true,如果获取失败(即锁已被其他线程获取),则返回false,
        也就说这个方法无论如何都会立即返回。在拿不到锁时不会一直在那等待。
    tryLock(long time, TimeUnit unit)
        这个方法在拿不到锁时会等待一定的时间,在时间期限之内如果还拿不到锁,就返回false。
        如果如果一开始拿到锁或者在等待期间内拿到了锁,则返回true。
    lockInterruptibly()
        在获取锁时,如果线程正在等待获取锁,则这个线程能够响应中断,即中断线程的等待状态。
        也就使说,当两个线程同时通过lock.lockInterruptibly()想获取某个锁时,
        假若此时线程A获取到了锁,而线程B只有在等待,那么对线程B调用threadB.interrupt()方法能够中断线程B的等待过程。
    
注意:
    使用Lock必须在try{}catch{}块中进行,并且将释放锁的操作放在finally块中进行,
    以保证锁一定被释放,防止死锁的发生。


http://www.niftyadmin.cn/n/1162526.html

相关文章

vue nextTick

由来: Vue中DOM更新是异步 Vue 实现响应式并不是数据发生变化之后 DOM 立即变化, 而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。 触发条件: 在同一事件循环中的数据变化后,DOM完…

js 实现继承

1. 对象冒充实例:var Parent function (username) {this.username usernamethis.getUserName function () {console.log(username: username)}}var Child function (username, age) {this.method Parentthis.method(username)delete this.methodthis.getAge …

vue 可拖拽table

Element UI下的示例&#xff1a; <template><div style"width:800px"><el-table :data"tableData"borderrow-key"id"align"left"><el-table-column v-for"(item, index) in col":key"col_${inde…

Android 环境下报错You have not accepted the license agreements of the following SDK components:

报错信息类似于&#xff1a; A problem occurred configuring project :app. > You have not accepted the license agreements of the following SDK components: [Android SDK Build-Tools 26.0.3, Android SDK Platform 26]. Before building your project, you nee…

使用AnyProxy监听移动端网络请求

AnyProxy是阿里公司分享的一款nodeJS中间件。其作用是可以用来监听移动端的接口访问以及参数请求&#xff0c;用通俗的语言这个叫做抓包。通过node的npm对AnyProxy本地化全局安装npm install -g anyproxy即可。可以通过npm config get prefix查看npm的安装目录&#xff0c;全局…

JS对象的引用复制和数据复制

JS对象分为两类&#xff0c;一类为基础类型对象&#xff0c;包括字符串(String)&#xff0c;数值(Number)&#xff0c;布尔值(Boolean)&#xff0c;null(空)&#xff0c;undefined(未定义)。另一类为合成对象&#xff0c;又叫做引用类型对象&#xff0c;包括数组(Array)&#x…

获取当前页面url的各类参数

Location 对象Location 对象包含有关当前 URL 的信息Location 对象是 Window 对象的一个部分&#xff0c;可通过 window.location 属性来访问Location的各种属性&#xff1a;window.location.hash > 设置或返回从井号 (#) 开始的 URL&#xff08;锚&#xff09;window.locat…

链接远程服务器

大多数情况下除服务器以外的个人PC多数采用的是window系统&#xff0c;在使用window系统连接远程云服务器时&#xff0c;需要根据云服务器的搭载系统采取不同的连接策略。 window系统连接搭载window系统的云服务器时&#xff0c;可以通过系统自带的远程连接功能创建连接。 win…