当前位置: 首页 > news >正文

Java线程安全

线程安全

  • 线程安全:
    • 线程安全:
      • synchronized
        • 同步代码块:
        • 同步方法:
          • 成员同步方法:
          • 静态同步方法:
      • Lock:
        • 应用:
    • 单例模式:
      • 懒汉式:
      • 饿汉式:
      • 枚举饿汉式:
      • 双重检验锁:

线程安全:

线程安全:

线程安全 – 加锁
注意:要想多个线程互斥住,就必须使用同一把锁(对象)!!!

加锁方式:

  1. synchronized
  2. Lock

 

synchronized

  1. 同步代码块
  2. 同步方法

 

同步代码块:

数据结构:

synchronized(锁对象){//自动上锁...想要互斥的代码...}//自动解锁

 

同步方法:
  1. 成员同步方法
  2. 静态同步方法

 

成员同步方法:

注意:锁对象 -> 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线程安全

线程安全 线程安全&#xff1a;线程安全&#xff1a;synchronized同步代码块:同步方法&#xff1a;成员同步方法:静态同步方法&#xff1a; Lock:应用&#xff1a; 单例模式&#xff1a;懒汉式&#xff1a;饿汉式&#xff1a;枚举饿汉式&#xff1a;双重检验锁&#xff1a; 线程…...

Solidity选择使用 require 语句还是条件语句结合手动触发 revert 操作?回滚交易和抛出异常如何选择?

文章目录 Solidity选择使用 require 语句还是条件语句结合手动触发 revert 操作&#xff1f;场景举例&#xff1a;回滚交易和抛出异常如何选择&#xff1f; Solidity选择使用 require 语句还是条件语句结合手动触发 revert 操作&#xff1f; 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 实现近邻算法以及优化方案

前言 近邻算法&#xff08;K-Nearest Neighbors&#xff0c;简称 KNN&#xff09;是一种简单的、广泛使用的分类和回归算法。它的基本思想是&#xff1a;给定一个待分类的样本&#xff0c;找到这个样本在特征空间中距离最近的 k 个样本&#xff0c;这 k 个样本的多数类别作为待…...

移动端适配和响应式页面中的常用单位

在移动端适配和响应式页面中&#xff0c;一般采用以下几种单位&#xff1a; 百分比&#xff08;%&#xff09;&#xff1a;百分比单位是相对于父元素的大小计算的。它可以用于设置宽度、高度、字体大小等属性&#xff0c;使得元素能够随着父元素的大小自动调整。百分比单位在响…...

麒麟v10系统arm64架构openssh9.7p1的rpm包

制作openssh 说明 理论上制作的多个rpm在arm64架构&#xff08;aarch64&#xff09;都适用 系统信息&#xff1a;4.19.90-17.ky10.aarch64 GNU/Linux 升级前备份好文件/etc/ssh、/etc/pam.d等以及开启telnet 升级后确认正常后关闭telnet 在之前制作过openssh-9.5p1基础上继续…...

刚刚❗️德勤2025校招暑期实习测评笔试SHL测评题库已发(答案)

&#x1f4e3;德勤 2024暑期实习测评已发&#xff0c;正在申请的小伙伴看过来哦&#x1f440; ㊙️本次暑期实习优先考虑2025年本科及以上学历的毕业生&#xff0c;此次只有“审计及鉴定”“税务与商务咨询”两个部门开放了岗位~ ⚠️测评注意事项&#xff1a; &#x1f44…...

python对视频进行帧处理以及裁减部分区域

视频截取帧 废话不多说直接上代码&#xff1a; from cv2 import VideoCapture from cv2 import imwrite# 定义保存图片函数 # image:要保存的图片名字 # addr&#xff1b;图片地址与相片名字的前部分 # num: 相片&#xff0c;名字的后缀。int 类型 def save_image(image, add…...

Python栈的编程题目

你好&#xff0c;我是悦创。 下面是三道关于栈的编程题目&#xff0c;适合不同难度级别的练习&#xff1a; 1. 有效的括号&#xff08;简单&#xff09; 题目描述&#xff1a; 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[ 和 ] 的字符串&#xf…...

ROS云课三分钟外传之CoppeliaSim_Edu_V4_1_0_Ubuntu16_04

三分钟热度试一试吧&#xff0c;走过路过不要错过。 参考之前&#xff1a; 从云课五分钟到一分钟之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地址 ** 本期本来是很有难度的&#xff0c;不过 大家做完 分割回文串 之后&#xff0c;本题就容易很多了 题目链接/文章讲解 | 视频讲解 class Solution { public:vector<string> result;// pointNum记录加入的点的数量&#xff0c;其等于3的时候停止void b…...

SpringBoot项目启动时“jar中没有主清单属性”异常

资料参考 Spring Boot 启动时 “jar中没有主清单属性” 异常 - spring 中文网 (springdoc.cn) 实际解决 更详细的参考以上&#xff0c;我这边的话只需要在 pom文件 中加上 spring-boot-maven-plugin 插件就能解决该异常&#xff0c;具体如下&#xff1a; <build><p…...

vAttention:用于在没有Paged Attention的情况下Serving LLM

文章目录 0x0. 前言&#xff08;太长不看版&#xff09;0x1. 摘要0x2. 介绍&背景0x3. 使用PagedAttention模型的问题0x3.1 需要重写注意力kernel0x3.2 在服务框架中增加冗余0x3.3 性能开销0x3.3.1 GPU上的运行时开销0x3.3.2 CPU上的运行时开销 0x4. 对LLM服务系统的洞察0x5…...

Python实现Stack

你好&#xff0c;我是悦创。 Python 中的栈结构是一种后进先出&#xff08;LIFO, Last In, First Out&#xff09;的数据结构&#xff0c;这意味着最后添加到栈中的元素将是第一个被移除的。栈通常用于解决涉及到反转、历史记录和撤销操作等问题。在 Python 中&#xff0c;你可…...

Helm在线部署Longhorn(1.6.0版本)分布式存储

环境依赖&#xff1a; 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、输入一棵二叉搜索树&#xff0c;将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点&#xff0c;只能调整树中结点指针的指向。 public class Solution {private Tr…...

DockerCompose中部署Jenkins(Docker Desktop在windows上数据卷映射)

场景 DockerJenkinsGiteeMaven项目配置jdk、maven、gitee等拉取代码并自动构建以及遇到的那些坑&#xff1a; DockerJenkinsGiteeMaven项目配置jdk、maven、gitee等拉取代码并自动构建以及遇到的那些坑_jenkins的安装以及集成jdkgitmaven 提示警告-CSDN博客 Windows10(家庭版…...

吊车报警的工作原理和使用场景_鼎跃安全

在现代建筑施工过程中&#xff0c;经常使用大型机械设备&#xff0c;如挖掘机、吊车、打桩机等&#xff0c;这些设备在施工过程中发挥着越来越重要的作用&#xff1b;同时&#xff0c;这些设备的作业频繁进行作业&#xff0c;对于接触到高压电线的风险也随之增加。大型机械设备…...

Spring5

文章目录 1. Spring 是什么&#xff1f;2. IoC3. Spring Demo4. IoC 创建对象的方式 / DI 方式注入的默认参数在哪里设定? 5. Spring 配置tx:annotation-driven 用于启用基于注解的事务管理 6. Bean的作用域7. 在Spring中有三种自动装配的方式1. 在xml中显式的配置2. 在java中…...

vue面试题二

一、请解释Vue中的双向数据绑定是什么&#xff1f; Vue中的双向数据绑定是一种机制&#xff0c;它使得数据的变化能够自动反映在用户界面上&#xff0c;同时用户界面中的输入也能够自动更新数据。这种机制实现了数据层&#xff08;Model&#xff09;和视图层&#xff08;View&…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端&#xff08;即页面 JS / Web UI&#xff09;与客户端&#xff08;C 后端&#xff09;的交互机制&#xff0c;是 Chromium 架构中非常核心的一环。下面我将按常见场景&#xff0c;从通道、流程、技术栈几个角度做一套完整的分析&#xff0c;特别适合你这种在分析和改…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器

一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下&#xff0c;音视频内容犹如璀璨繁星&#xff0c;点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频&#xff0c;到在线课堂中知识渊博的专家授课&#xff0c;再到影视平台上扣人心弦的高清大片&#xff0c;音…...