Java线程安全
线程安全
- 线程安全:
- 线程安全:
- synchronized
- 同步代码块:
- 同步方法:
- 成员同步方法:
- 静态同步方法:
- Lock:
- 应用:
- 单例模式:
- 懒汉式:
- 饿汉式:
- 枚举饿汉式:
- 双重检验锁:
线程安全:
线程安全:
线程安全 – 加锁
注意:要想多个线程互斥住,就必须使用同一把锁(对象)!!!
加锁方式:
- synchronized
- Lock
synchronized
- 同步代码块
- 同步方法
同步代码块:
数据结构:
synchronized(锁对象){//自动上锁...想要互斥的代码...}//自动解锁
同步方法:
- 成员同步方法
- 静态同步方法
成员同步方法:
注意:锁对象 -> this
多个子线程时,调用的对象(this)不一样,则锁不住。
数据结构:
public synchronized void method(){//自动上锁...想要互斥的代码...}//自动解锁
静态同步方法:
注意:锁对象 -> 类.class
public static synchronized void method(){//自动上锁...想要互斥的代码...}//自动解锁
Lock:
//锁对象Lock lock = new ReentrantLock();lock.lock();//手动上锁...想要互斥的代码...lock.unlock();//手动解锁
应用:
public class MyThread extends Thread{private static int allTicket = 1000;private static int curTicket = 0;private static Lock lock = new ReentrantLock();public MyThread(String name) {super(name);}@Overridepublic void run() {while(curTicket < allTicket){lock.lock();//手动上锁try {if(curTicket < allTicket){curTicket++;System.out.println("窗口" + Thread.currentThread().getName() + "正在销售第" + curTicket + "张票");}if(curTicket >= allTicket){System.out.println("窗口" + Thread.currentThread().getName() + "票已经售完");}} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();//手动解锁}}}}
public static void main(String[] args) {MyThread t1 = new MyThread("001");MyThread t2 = new MyThread("002");MyThread t3 = new MyThread("003");t1.start();t2.start();t3.start();}
单例模式:
该类的对象在整个项目中只创建一次(只实例化一次)。
懒汉式:
单例模式(懒汉式)不是线程安全的。
public class A {//声明对象名private static A a;private A(){}public static A getIntance(){//判断对象为空,再创建对象if(a == null){a = new A();}return a;}
}
public static void main(String[] args) {A a1 = A.getIntance();A a2 = A.getIntance();A a3 = A.getIntance();A a4 = A.getIntance();//地址都是一样的,则是一个对象System.out.println(a1);System.out.println(a2);System.out.println(a3);System.out.println(a4);}
饿汉式:
单例模式(饿汉式)是线程安全的。
public class A {//先创建对象private static A a = new A();private A(){}public static A getIntance(){return a;}public static void method(){System.out.println("用良心做教育");}
}
public static void main(String[] args) {A a1 = A.getIntance();A a2 = A.getIntance();A a3 = A.getIntance();A a4 = A.getIntance();System.out.println(a1);System.out.println(a2);System.out.println(a3);System.out.println(a4);}
缺点:如果只调用了类里的静态方法,没用到单例对象,就是浪费空间。
public static void main(String[] args) {A.method();}
枚举饿汉式:
枚举单例模式(饿汉式)是线程安全的。
public enum A {//public static final A a = new A();a;private A(){}public static A getIntance(){return a;}public static void method(){System.out.println("用良心做教育");}@Overridepublic String toString() {return String.valueOf(a.hashCode());}
}
public static void main(String[] args) {A a1 = A.getIntance();A a2 = A.getIntance();A a3 = A.getIntance();A a4 = A.getIntance();System.out.println(a1);System.out.println(a2);System.out.println(a3);System.out.println(a4);}
缺点:如果只调用了枚举里的静态方法,没用到单例对象,就是浪费空间。
public static void main(String[] args) {A.method();}
双重检验锁:
项目中使用的单例模式------->双重检验锁。
双重检验锁的单例模式是线程安全的。
volatile – 防止指令重排
创建对象的过程: a.开辟空间 ----- new 对象() – 0x001
b.调用构造方法 – 初始化数据
c.将空间赋值给引用 – 类型 引用 = 0x001
创建对象的步骤:a/b/c 或 a/c/b
注意:如果创建对象的步骤是a/c/b,多线程的情况下可能会导致获取的属性为null
解决方案:使用volatile,防止指令重排,创建的步骤必须按照a/b/c
public class A {private static volatile A a;private A(){}public static A getIntance(){if(a == null){synchronized (A.class) {if(a == null){a = new A();}}}return a;}// public static A getIntance(){
//
// if(a != null){
// return a;
// }
// synchronized (A.class) {
// if(a == null){
// a = new A();
// }
// }
// return a;
// }
}
public static void main(String[] args) {A a1 = A.getIntance();A a2 = A.getIntance();A a3 = A.getIntance();A a4 = A.getIntance();System.out.println(a1);System.out.println(a2);System.out.println(a3);System.out.println(a4);}
相关文章:
Java线程安全
线程安全 线程安全:线程安全:synchronized同步代码块:同步方法:成员同步方法:静态同步方法: Lock:应用: 单例模式:懒汉式:饿汉式:枚举饿汉式:双重检验锁: 线程…...
Solidity选择使用 require 语句还是条件语句结合手动触发 revert 操作?回滚交易和抛出异常如何选择?
文章目录 Solidity选择使用 require 语句还是条件语句结合手动触发 revert 操作?场景举例:回滚交易和抛出异常如何选择? Solidity选择使用 require 语句还是条件语句结合手动触发 revert 操作? IERC721 nft IERC721(nftAddress)…...
SpringCloud 网关配置websocket
一、nginx https://域名.com location /websocket/ { proxy_pass http://172.1.1.173:8181/; #内网网关IP proxy_http_version 1.1; proxy_read_timeout 360s; proxy_redirect off; proxy_set_header Upgrade $http_upgrade; …...
基于JavaScript 实现近邻算法以及优化方案
前言 近邻算法(K-Nearest Neighbors,简称 KNN)是一种简单的、广泛使用的分类和回归算法。它的基本思想是:给定一个待分类的样本,找到这个样本在特征空间中距离最近的 k 个样本,这 k 个样本的多数类别作为待…...
移动端适配和响应式页面中的常用单位
在移动端适配和响应式页面中,一般采用以下几种单位: 百分比(%):百分比单位是相对于父元素的大小计算的。它可以用于设置宽度、高度、字体大小等属性,使得元素能够随着父元素的大小自动调整。百分比单位在响…...
麒麟v10系统arm64架构openssh9.7p1的rpm包
制作openssh 说明 理论上制作的多个rpm在arm64架构(aarch64)都适用 系统信息:4.19.90-17.ky10.aarch64 GNU/Linux 升级前备份好文件/etc/ssh、/etc/pam.d等以及开启telnet 升级后确认正常后关闭telnet 在之前制作过openssh-9.5p1基础上继续…...
刚刚❗️德勤2025校招暑期实习测评笔试SHL测评题库已发(答案)
📣德勤 2024暑期实习测评已发,正在申请的小伙伴看过来哦👀 ㊙️本次暑期实习优先考虑2025年本科及以上学历的毕业生,此次只有“审计及鉴定”“税务与商务咨询”两个部门开放了岗位~ ⚠️测评注意事项: ὄ…...
python对视频进行帧处理以及裁减部分区域
视频截取帧 废话不多说直接上代码: from cv2 import VideoCapture from cv2 import imwrite# 定义保存图片函数 # image:要保存的图片名字 # addr;图片地址与相片名字的前部分 # num: 相片,名字的后缀。int 类型 def save_image(image, add…...
Python栈的编程题目
你好,我是悦创。 下面是三道关于栈的编程题目,适合不同难度级别的练习: 1. 有效的括号(简单) 题目描述: 给定一个只包括 (,),{,},[ 和 ] 的字符串…...
ROS云课三分钟外传之CoppeliaSim_Edu_V4_1_0_Ubuntu16_04
三分钟热度试一试吧,走过路过不要错过。 参考之前: 从云课五分钟到一分钟之v-rep_pro_edu_v3_6_2-CSDN博客 git clone https://gitcode.net/ZhangRelay/v-rep_pro_edu_v3_6_2_ubuntu16_04.gittar -xf v-rep_pro_edu_v3_6_2_ubuntu16_04/V-REP_PRO_EDU…...
day28回溯算法part04| 93.复原IP地址 78.子集 90.子集II
**93.复原IP地址 ** 本期本来是很有难度的,不过 大家做完 分割回文串 之后,本题就容易很多了 题目链接/文章讲解 | 视频讲解 class Solution { public:vector<string> result;// pointNum记录加入的点的数量,其等于3的时候停止void b…...
SpringBoot项目启动时“jar中没有主清单属性”异常
资料参考 Spring Boot 启动时 “jar中没有主清单属性” 异常 - spring 中文网 (springdoc.cn) 实际解决 更详细的参考以上,我这边的话只需要在 pom文件 中加上 spring-boot-maven-plugin 插件就能解决该异常,具体如下: <build><p…...
vAttention:用于在没有Paged Attention的情况下Serving LLM
文章目录 0x0. 前言(太长不看版)0x1. 摘要0x2. 介绍&背景0x3. 使用PagedAttention模型的问题0x3.1 需要重写注意力kernel0x3.2 在服务框架中增加冗余0x3.3 性能开销0x3.3.1 GPU上的运行时开销0x3.3.2 CPU上的运行时开销 0x4. 对LLM服务系统的洞察0x5…...
Python实现Stack
你好,我是悦创。 Python 中的栈结构是一种后进先出(LIFO, Last In, First Out)的数据结构,这意味着最后添加到栈中的元素将是第一个被移除的。栈通常用于解决涉及到反转、历史记录和撤销操作等问题。在 Python 中,你可…...
Helm在线部署Longhorn(1.6.0版本)分布式存储
环境依赖: k8s (版本大于等于v1.21版本)、helm工具 安装前准备 k8s worker 节点都需要执行 yum -y --setopttsflagsnoscripts install iscsi-initiator-utils echo "InitiatorName$(/sbin/iscsi-iname)" > /etc/iscsi/initiatorname.iscsi systemctl …...
算法题目学习汇总
1、二叉树前中后序遍历:https://blog.csdn.net/cm15835106905/article/details/124699173 2、输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。 public class Solution {private Tr…...
DockerCompose中部署Jenkins(Docker Desktop在windows上数据卷映射)
场景 DockerJenkinsGiteeMaven项目配置jdk、maven、gitee等拉取代码并自动构建以及遇到的那些坑: DockerJenkinsGiteeMaven项目配置jdk、maven、gitee等拉取代码并自动构建以及遇到的那些坑_jenkins的安装以及集成jdkgitmaven 提示警告-CSDN博客 Windows10(家庭版…...
吊车报警的工作原理和使用场景_鼎跃安全
在现代建筑施工过程中,经常使用大型机械设备,如挖掘机、吊车、打桩机等,这些设备在施工过程中发挥着越来越重要的作用;同时,这些设备的作业频繁进行作业,对于接触到高压电线的风险也随之增加。大型机械设备…...
Spring5
文章目录 1. Spring 是什么?2. IoC3. Spring Demo4. IoC 创建对象的方式 / DI 方式注入的默认参数在哪里设定? 5. Spring 配置tx:annotation-driven 用于启用基于注解的事务管理 6. Bean的作用域7. 在Spring中有三种自动装配的方式1. 在xml中显式的配置2. 在java中…...
vue面试题二
一、请解释Vue中的双向数据绑定是什么? Vue中的双向数据绑定是一种机制,它使得数据的变化能够自动反映在用户界面上,同时用户界面中的输入也能够自动更新数据。这种机制实现了数据层(Model)和视图层(View&…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
