[Java、Android面试]_09_Synchronized、volatile、Lock并发

本人今年参加了很多面试,也有幸拿到了一些大厂的offer,整理了众多面试资料,后续还会分享众多面试资料。

整理成了面试系列,由于时间有限,每天整理一点,后续会陆续分享出来,感兴趣的朋友可关注+收藏

文章目录

    • 1. 简介
    • 2. sychronized关键字的用法
    • 3. Lock的底层原理-CAS(Compare and Swap)
    • 4. sychronized底层原理

1. 简介

(1)Synchronized
synchronized 是 Java 中的关键字,用于实现线程同步和互斥,只能是非公平锁。它可以用于方法或代码块中,确保在同一时间只有一个线程可以访问同步代码。使用 synchronized 可以保证线程安全,但可能会引起性能问题,因为它会导致线程阻塞等待锁的释放。

1.public synchronized void synchronizedMethod() {  
2.    // 同步的代码块  
3.}  

(2)Volatile
volatile 是用于修饰变量的关键字,它确保了可见性和禁止指令重排序。当一个变量被声明为 volatile 时,对该变量的写操作会立即被刷新到主内存,对该变量的读操作会从主内存中获取最新的值。volatile 可用于保证多线程环境下的变量的一致性,但它不能解决复合操作问题。

1.private volatile int counter = 0;  

(3)Lock 接口及其实现
Java提供了 Lock 接口及其实现类,如 ReentrantLock,用于实现更灵活的线程同步机制,可实现公平锁和非公平锁。与 synchronized 相比,Lock 可以支持更多的特性,如可重入性、公平性、条件等待等。Lock 的使用需要显式地获取锁和释放锁,可以更细粒度地控制线程的同步。
它的底层是使用CAS+自旋实现的。

1.import java.util.concurrent.locks.Lock;  
2.import java.util.concurrent.locks.ReentrantLock;  
3.public class LockExample {  
4.    private Lock lock = new ReentrantLock();  
5.    public void lockedMethod() {  
6.        lock.lock();  
7.        try {  
8.            // 临界区代码  
9.        } finally {  
10.            lock.unlock();  
11.        }  
12.    }  
13.}

注:
公平锁: 多个线程按照申请锁的顺序去获得锁,线程会直接进入队列去排队,永远都是队列的第一位才能得到锁;

非公平锁: 多个线程去获取锁的时候,会直接去尝试获取,获取不到,再去进入等待队列,如果能获取到,就直接获取到锁。

2. sychronized关键字的用法

(1)sychronized修饰方法/代码块

1.// 两种修饰方法的方式等效
2.public synchronized void test1(){
3.        //do something
4.    }
5.public void test2(){
6.        synchronized (this){
7.            //do something
8.        }
9.    }
作用对象都是单个实例,作用范围都是相应的代码块(方法)。示例如下:
1.public class SychronizedTest implements Runnable{
2.    @Override
3.    public void run() {
4.        synchronized(this){
5.            for (int i = 0; i < 5; i++) {
6.                System.out.println(Thread.currentThread().getName() + " " + i);
7.            }
8.        }
9.    }
10.}
1.public class Main {
2.    public static void main(String[] args) {
3.        SychronizedTest testThis = new SychronizedTest();
4.        new Thread(testThis, "one").start();
5.        new Thread(testThis, "two").start();
6.    }
7.}

输出结果如下:
在这里插入图片描述

分析如下:
因为第一个线程先访问到run()方法,所以它先拿到锁,two线程则阻塞,所以输出是先one线程输出,two线程后输出。

(2)sychronized修饰 static方法
当synchronized修饰静态方法时,锁的作用对象是类,作用范围是该类的所有对象的static synchronized 方法。

即,当一个线程执行到某个对象被synchronized修饰的静态方法时, 该对象的类下所有对象的static synchronized 方法都被该线程加锁了,都不能动了,但其他的不受影响 。示例如下:

1.public class TestStatic implements Runnable{
2. @Override
3. public void run() {
4.        String threadName = Thread.currentThread().getName()+"";
5.        if (threadName.equals("A")){
6.            testA();
7.        }else if (threadName.equals("B")){
8.            testB();
9.        }else if (threadName.equals("C")){
10.            testC();
11.        }else if (threadName.equals("D")){
12.            testD();
13.        }else{
14.            testE();
15.        }
16.  
17. }
18.   // 类锁
19.    public synchronized static void testA(){
20.        for(int i=0; i<5; i++){
21.            System.out.println(Thread.currentThread().getName()+" "+i);
22.        }
23.    }
24.   // 类锁
25.    public synchronized static void testB(){
26.        for(int i=0; i<5; i++){
27.            System.out.println(Thread.currentThread().getName()+" "+i);
28.        }
29.    }
30.   // 对象锁
31.    public synchronized void testC(){
32.        for(int i=0; i<5; i++){
33.            System.out.println(Thread.currentThread().getName()+" "+i);
34.        }
35.    }
36.  // 对象锁
37.    public synchronized void testD(){
38.        for(int i=0; i<5; i++){
39.            System.out.println(Thread.currentThread().getName()+" "+i);
40.        }
41.    }
42.
43.    public void testE(){
44.        for(int i=0; i<5; i++){
45.            System.out.println(Thread.currentThread().getName()+" "+i);
46.        }
47.    }
48.}

调用:

1.public class SychronizedMain {
2.    public static void main(String[] args) {
3.        TestStatic testStatic = new TestStatic();
4.        new Thread(testStatic, "A").start();
5.        new Thread(testStatic, "B").start();
6.        new Thread(testStatic, "C").start();
7.        new Thread(testStatic, "D").start();
8.        new Thread(testStatic, "E").start();
9.    }
10.}

结果:
在这里插入图片描述

对象锁、类锁的总结:

从上面的示例中,可以得出:
· 类锁就是 sychronized static, 其他就是对象锁; ·
· 对象锁和类锁是独立的,即一个线程持有了对象锁并不影响其他线程获取类锁,反之亦然。

(3)sychronized与wait()和notify()的使用

  1. wait()与notify()都是Object的方法

  2. wait()与notify()都只能在synchronized方法或代码块中使用

  3. 当一个线程执行到wait()方法时,该线程会释放锁(同时释放CPU资源),并对执行
    点进行标记,当该线程被重新唤醒时,会从标记点继续执行代码

  4. 由于线程执行wait()时会释放锁,这意味着:
    当一个线程执行到了wait(),其他线程则可以进入:当该线程被唤醒时,它需要重新对
    相应的对象进行加锁,如果某对象的全部线程被唤醒了(notifyAll())则它们需要竞争来确定谁先加锁。

  5. 当一个线程执行到notify()时,它不会立即释放锁,而是要把sychronized()代码块执行完后再进行释放锁;

  6. notify()选择唤醒的线程是随机的,但是依赖与具体实现的jvm, 如再hotspot中就是先wait()先唤醒。

3. Lock的底层原理-CAS(Compare and Swap)

lock的存储结构:一个int类型状态值(用于锁的状态变更),一个双向链表(用于存储等待中的线程)

lock获取锁的过程:本质上是通过CAS来获取状态值修改,如果当场没获取到,会将该线程放在线程等待链表中。

lock释放锁的过程:修改状态值,调整等待链表。

可以看到在整个实现过程中,lock大量使用CAS+自旋。因此根据CAS特性,lock建议使用在低锁冲突的情况下。目前java1.6以后,官方对synchronized做了大量的锁优化(偏向锁、自旋、轻量级锁)。因此在非必要的情况下,建议使用synchronized做同步操作。

4. sychronized底层原理

简单来说就是有两个标识位,当代码走到monitorenter的时候,虚拟机就知道后面的代码是需要保证线程安全的,只能让一个线程同时操作,当代码走到monitorexit的时候,虚拟机就知道同步结束,后面的代码无需保证安全。

本节完!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/762414.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自上而下的角色扮演游戏资产包幻想梦境

Fantasy Dreamland 是一個完整的資源包,包含開始製作自上而下的像素藝術遊戲所需的一切! 幻想夢境瓷磚套裝: - 超過 13,000 塊瓷磚! - 超過 500 個動畫圖塊! - 鐵匠! - 城堡! - 洞穴! - 聖誕節! (裝飾) - 城市! - 沙漠! - 沙漠房屋! - 夢想/天空! - …

【解决】使用Jekyll框架进入网页终端返回找不到.min.js或者类似Rollup模块化构建js失败问题

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 文章目录 一、问题表现二、问题解决&#xff08;一&#xff09;检查输出目录&#xff08;二&#xff09;启动Rollup构建 三、…

PCD1000AE单通道高压线性恒流LED控制芯片

概述 PCD1000AE 是一款线性恒流 IC&#xff0c;输出电流可调&#xff0c;恒流精度高&#xff0c;应用方案简单&#xff0c;成本和阻容降压相当&#xff0c;具有过温保护功能&#xff0c;更安全&#xff0c;更可靠。 特点 输出电流可调 5mA-60mA&#xff0c; 恒流精度可以达…

【C++】vector容器初步模拟

送给大家一句话&#xff1a; 努力一点&#xff0c;漂亮—点&#xff0c;阳光一点。早晚有一天&#xff0c;你会惊艳了时光&#xff0c;既无人能替&#xff0c;又光芒万丈。 vector容器初步模拟 1 认识vector开始了解底层实现 2 开始实现成员变量构造函数 析构函数尾插迭代器插入…

【漏洞复现】福建科立迅通信指挥调度平台down_file.php sql注入漏洞

漏洞描述 福建科立迅通信调度平台 20240318 以及之前版本存在一个严重漏洞,影响了文件 api/client/down_file.php 的一个未知功能。攻击者可以通过操纵参数 uuid 发起 SQL 注入攻击。攻击者可以远程发起攻击。 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守…

GraalVM详细安装及打包springboot、java、javafx使用教程(打包springboot2篇)

前言 在当前多元化开发环境下&#xff0c;Java作为一种广泛应用的编程语言&#xff0c;其应用部署效率与灵活性的重要性日益凸显。Spring Boot框架以其简洁的配置和强大的功能深受开发者喜爱&#xff0c;而JavaFX则为开发者提供了构建丰富桌面客户端应用的能力。然而&#xff…

基于Java中的SSM框架实现图书仓储管理系统项目【项目源码+论文说明】

基于Java中的SSM框架实现图书仓储管理系统演示 摘要 随着社会经济的迅速发展和科学技术的全面进步&#xff0c;计算机事业的飞速发展&#xff0c;以计算机与通信技术为基础的信息系统正处于蓬勃发展的时期&#xff0c;随着经济文化水平的显著提高&#xff0c;人们对生活质量及…

【视频图像取证篇】模糊图像增强技术之锐化类滤波场景应用小结

【视频图像取证篇】模糊图像增强技术之锐化类滤波场景应用小结 模糊图像增强技术之锐化类滤波场景应用小结—【蘇小沐】 &#xff08;一&#xff09;锐化类滤波器 模糊消除类滤波器&#xff08;Remove blur / Unsharpness&#xff09;。 通用去模糊滤波器&#xff1a;针对大…

(ROOT)KAFKA详解

生产篇 使用 /** Licensed to the Apache Software Foundation (ASF) under one or more* contributor license agreements. See the NOTICE file distributed with* this work for additional information regarding copyright ownership.* The ASF licenses this file to Y…

#Linux(环境变量)

&#xff08;一&#xff09;发行版&#xff1a;Ubuntu16.04.7 &#xff08;二&#xff09;记录&#xff1a; &#xff08;1&#xff09;查看环境变量 &#xff08;2&#xff09;修改环境变量 第一种方法&#xff1a;直接使用命令设置&#xff08;立即生效&#xff0c;只会作用…

了解交换机上的SFP和QSFP端口

在当今互联的世界中&#xff0c;可靠、高效的网络通信对于企业的蓬勃发展至关重要。为了实现顺畅的连接&#xff0c;了解能够实现该目标的技术非常重要。其中一项关键技术是交换机上的SFP和QSFP端口。本文将简要介绍这些概念&#xff0c;定义并解释交换机SFP端口和QSFP端口的优…

视频私有云,HDMI/AV多硬件设备终端接入,SFU/MCU视频会议交互方案。

在视频业务深入的过程中越来越多的硬件设备接入视频交互的视频会议中远程交互&#xff0c;有的是视频采集&#xff0c;有的是医疗影像等资料&#xff0c;都需要在终端承显&#xff0c;这就需要我们的设备终端能多设备&#xff0c;多协议接入&#xff0c;设备接入如下。 1&#…

软件应用,宠物医院兽医开的处方单管理系统软件教程,宠物店营业软件教程

软件应用&#xff0c;宠物医院兽医开的处方单管理系统软件教程&#xff0c;宠物店营业软件教程 一、前言 以下软件操作教程以 佳易王宠物医院兽医处方软件V17.0为例说明 件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 在开处方单的时候&#xff0c;可以打…

工程信号的去噪和(分类、回归和时序)预测

&#x1f680;【信号去噪及预测论文代码指导】&#x1f680; 还为小论文没有思路烦恼么&#xff1f;本人专注于最前沿的信号处理与预测技术——基于信号模态分解的去噪算法和深度学习的信号&#xff08;回归、时序和分类&#xff09;预测算法&#xff0c;致力于为您提供最精确、…

硬核分享|免费快速的高保真图片压缩方案

硬核分享|免费快速的高保真图片压缩方案_哔哩哔哩_bilibili 在当今数字化时代&#xff0c;图像已然成为我们日常生活中必不可少的元素之一。但是&#xff0c;伴随着高清相机与日俱增以及拍摄照片数量的飞速增长&#xff0c;如何安全、高效的存储和传播海量图片已逐渐成为亟待解…

户外水质检测显示屏用于检测并显示各种水质数据

水质检测一直是环境保护和公共卫生领域的重要课题。随着科技的不断进步&#xff0c;水质检测设备也在不断更新换代。其中&#xff0c;水质检测显示屏作为一种新型的检测设备&#xff0c;为监测和显示各种水质数据提供了便利和高效的手段。 水质检测显示屏是一种集成了传感器、数…

CSS 让元素根据内容自适应宽度

一、需求 点击链接跳转&#xff0c;只点击标红区域才跳转&#xff0c;右侧空白区域不要跳转 二、实现 宽度太宽&#xff0c;导致右侧空白区域也加了跳转效果&#xff0c;修改为 将元素的最大宽度设置为其内容所需的宽度。 方法一&#xff1a;建议方式 使用 display: inline…

Excel的数据分析工具

Excel的数据分析工具 会生成新的工作簿 全选--数据透视表 插入切片器 使用作图工具 可以继续插入条件切片

数据结构:图的拓扑排序与关键路径

目录 一、拓扑排序 1.1、算法的基本步骤 1.2、算法实现 1.3、习题思考 1.4、DFS生成逆拓扑序 二、关键路径 1.1、关键路径的原理 1.2、算法的基本步骤 1.3、算法实现 1.4、习题思考 一、拓扑排序 ➢ AOV网:在 有向图中&#xff0c; 顶点表示活动&#xff08;或任务&a…

Android ViewPager不支持wrap_content的原因

文章目录 Android ViewPager不支持wrap_content的原因问题源码分析解决 Android ViewPager不支持wrap_content的原因 问题 <androidx.viewpager.widget.ViewPagerandroid:id"id/wrap_view_pager"android:layout_width"match_parent"android:layout_he…