线程安全之Synchronized

synchronized解决线程安全问题 应用之互斥 为了避免临界区的竞态条件发生,有多种手段可以达到目的。 阻塞式的解决方案:synchronized、Lock 非阻塞式的解决方案:原子变量 synchronized:俗称的对象锁,它采用互斥的方式让同一时刻至多只有一个线程拥有对象锁,其它线程再想获取这个对象锁的时候就会阻塞住,这样就能保证拥有锁的线程可以安全的执行临界区内的代码,不用担心线程上下文切换。 注意:虽然Java中互斥和同步都可以使用synchronized关键字来完成,但是它们是有区别的: 互斥是保证临界区的竞态条件发生 阅读详情

线程安全问题的主要诱因
1、存在共享数据(也称临界资源)
2、存在多条线程共同操作这些共享数据
解决问题的根本方法:
同一时刻有且只有一个线程在操作共享数据,其他线程必须等到该线程处理完数据后再对共享数据进行操作

互斥锁的特性
互斥性:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程的协调机制,这样在同一时间只有一个线程对需要同步的代码块(复合操作)进行访问。互斥性也称为操作的原子性。
可见性:必须确保在锁被释放之前,对共享变量所作的修改,对于随后获得该锁的另一个线程是可见的(即在获得锁时应获得最新共享变量的值),否则另一个线程可能是在本地缓存的某个副本上继续操作,从而引起不一致。
synchronized锁的不是代码,锁的都是对象

根据获取的锁的分类:获取对象锁和获取类锁
获取对象锁的两种方法:
1、同步代码块(synchronized(this),synchronized(类实列对象)),锁是小括号中的实列对象。
2、同步非静态方法(synchronized method),锁是当前对象的实列对象。
获取类锁的两种方法:
1、同步代码块(synchronized (类.class)),锁是小括号()中的类对象(Class对象)。
2、同步静态方法(synchronized static method),锁是当前对象的类对象(Class对象)。

import java.text.SimpleDateFormat;
import java.util.Date;

public class SynchronizedThread implements Runnable {
	
	public void run() {
		String threadName = Thread.currentThread().getName();
		if(threadName.startsWith("A")) {
			async();
		}else if(threadName.startsWith("B")) {
			syncObjectBlock();
		}else if(threadName.startsWith("C")) {
			syncObjectMethod();
		}
	}
	
	/**
	 * 异步方法
	 */
	private void async() {
		System.out.println(Thread.currentThread().getName() + "-已进入异步方法: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:sss").format(new Date()));
		try {
			System.out.println(Thread.currentThread().getName() + "-异步方法执行开始: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:sss").format(new Date()));
			Thread.sleep(1000);
			System.out.println(Thread.currentThread().getName() + "-异步方结束执行: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:sss").format(new Date()));
		}catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 同步代码块
	 */
	private void syncObjectBlock() {
		System.out.println(Thread.currentThread().getName() + "-已进入同步代码块: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:sss").format(new Date()));
		synchronized (this) {
			try {
				System.out.println(Thread.currentThread().getName() + "-同步代码块执行开始: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:sss").format(new Date()));
				Thread.sleep(1000);
				System.out.println(Thread.currentThread().getName() + "-同步代码块执行结束: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:sss").format(new Date()));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 非静态方法
	 */
	private synchronized void syncObjectMethod() {
		System.out.println(Thread.currentThread().getName() + "-已进入非静态同步方法: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:sss").format(new Date()));
		try {
			System.out.println(Thread.currentThread().getName() + "-非静态同步方法执行开始: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:sss").format(new Date()));
			Thread.sleep(1000);
			System.out.println(Thread.currentThread().getName() + "-非静态同步方法执行结束: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:sss").format(new Date()));
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

}

public class SyncDemo {
	public static void main(String[] args) {
		SynchronizedThread syncThread = new SynchronizedThread();
		Thread A_thread1 = new Thread(syncThread, "A_1");
		Thread A_thread2 = new Thread(syncThread, "A_2");
		Thread B_thread1 = new Thread(syncThread, "B_1");
		Thread B_thread2 = new Thread(syncThread, "B_2");
		Thread C_thread1 = new Thread(syncThread, "C_1");
		Thread C_thread2 = new Thread(syncThread, "C_2");
		A_thread1.start();
		A_thread2.start();
		B_thread1.start();
		B_thread2.start();
		C_thread1.start();
		C_thread2.start();
	}
}

打印结果
在这里插入图片描述
对象锁和类锁的总结
1、有线程访问对象的同步代码块时,另外的线程可以访问该对象的非同步代码块;
2、若锁住的是同一个对象,一个线程在访问对象的同步代码块时,另一个访问对象的同步代码块的线程会被阻塞;
3、若锁住的是同一个对象,一个线程在访问对象的同步方法时,另一个访问对象同步方法的线程会被阻塞;
4、若锁住的是同一个对象,一个线程在访问对象的同步代码块时,另一个访问对象同步方法的线程会被阻塞,反之亦然;
5、同一个类的不同对象的对象锁互不干扰;
6、类锁由于也是一种特殊的对象锁,因此表现和上述1,2,3,4一致,而由于一个类只有一把对象锁,所以同一个类的不同对象使用类锁将会是同步的;
7、类锁和对象锁互不干扰。

线程安全你还在用synchronized? 你还在用synchronized?线程安全相关知识深入剖析 立即下载

相关推荐

【工具】GitHub学生认证+PyCharm配置Copilot全流程指南

本文提供了一份详细的GitHub学生认证及在PyCharm中配置Copilot的完整指南。通过完成A2F认证、准备有效材料并使用干净网络环境,学生可免费获取GitHub Copilot Pro订阅,极大提升编程学习与开发效率。

w7x8y9z的博客 1459

线程安全——Synchronized

synchronized的几种用法修饰普通方法,相当于锁实例对象对代码块进行加锁,相当于锁当前调用方法的对象(也是实例对象)对静态方法进行加锁,相当于锁类对象。

WangSir 1102

【从零开始玩量化1】AKShare: Python开源财经数据接口库

文章目录量化的第一步:数据AKShare介绍AKShare安装AKShare使用AKTools安装/使用结语 量化的第一步:数据 想要玩量化,第一步要有数据,这个数据可能是历史交易数据、财务数据、宏观数据等等。我们最终要做的,无非就是从数据中分析出有价值的信息,以便用来指导投资策略。 在获取数据的这条道路上,我走了很多弯路,尝试了各种方法:使用Tushare到放弃、自己写网易股票页面的爬虫,自己写申万行业数据的爬虫、自己写同花顺问财的爬虫、使用聚宽的免费数据API等等,直到最终,我发现了AKShare。 A

量化投资助手的博客 5万+

[SpringBoot的@Async注解和关键字synchronized的使用]

SpringBoot的@Async的详细使用说明,带样例,以及关键字synchronized同步代码块的使用

虽千万人,吾往矣 6410

基于大模型的JMeter日志智能分析服务化实践

在软件性能测试领域,日志分析是定位系统瓶颈、评估稳定性的关键环节。传统基于规则或正则表达式的分析方法,在面对格式多变、上下文关联复杂的海量日志时,往往效率低下且难以深入。大语言模型(LLM)凭借其强大的自然语言理解与推理能力,为这一挑战提供了新的解决方案。其技术价值在于能够自动化地从非结构化文本中提取语义信息、关联分散的上下文,并生成可操作的根因分析与优化建议,从而将工程师从繁琐的日志筛查中解放出来,显著提升问题诊断的深度与效率。这一技术可广泛应用于自动化测试报告生成、实时监控预警、脚本调试辅助等工程实践场

weixin_28839549的博客 338

新华硕笔记本ubuntu18.04双系统安装之后,wifi没有显示无法链接wifi

本来我以为跟简单安装一个wifi网卡的驱动就可以解决的问题,没想到花了我一早上的时候解决… 惭愧。 另外,本来是没打算写这篇博客的,但是我在搜索解决这个问题的过程中, 发现多人提出的解决方案跟我的都不一样,甚至我的解决方案都没有搜到相应的答案,还是只能靠自己啊。。 言归正传,还是说说怎么正确的安装wifi驱动吧! 1. wifi没有正确安装、或没有正确配置的表现 我的电脑现象: 有wifi图标, wifi设置上显示unaviable,无法搜索到任何wifi; 还有其他类似的表现,大家可以看看其他朋友的提

Ian的博客 1889

在静态方法和非静态方法上加 Synchronized的区别

Synchronzied 修饰非静态方法==》对象锁 Synchronzied 修饰静态方法==》其实是类锁,因为是静态方法,它把整个类锁起来了; 情况1:同一个对象在两个线程中分别访问该对象的两个同步方法 结果:会产生互斥。 解释:因为锁针对的是对象,当对象调用一个synchronized方法时,其他同步方法需要等待其执行结束并释放锁后才能执行。 情况2:不同对象在两个线程中调用同一个同步方法 结果:不会产生互斥。 解释:因为是两个对象,锁针对的是对象,并不是方法,所以可以并发执行,不会互斥。形象的来说就

sinat_34620530的博客 618

Cartographer实现双雷达建图

TRAJECTORY_BUILDER_2D.num_accumulated_range_data = 2 --执行一次前端匹配需要的激光扫描分段数量。关于num_subdivisions_per_laser_scan。num_laser_scans =2,--订阅激光扫描话题数量。Frame改为 前雷达laser_1 后雷达laser_2。雷达的话题由scan改为,前scan_1 后scan_2。有些人说需要改成2,但我这里改成2反而不行,1才可以。

Studying…… 1261

线程安全问题(synchronized解决,各种类型全)

1. java中的同步方法会增加你程序的性能的消耗,所以只有在正真需要的时候才使用同步。使用同步代码块是需要保护资源才使用 2.静态方法加锁,和xx.class 锁效果一样,都是类锁 3.“this锁”需要强调的是,关于同一个类的方法上的锁,来自于调用该方法的对象,如果调用该方法的对象是相同的,那么锁必然相同,否则就不相同。比如 new A().x() 和 new A().x(),对象不同,锁不同。

hongs468的博客 1179

AI原生应用API编排:如何实现高效的权限管理?

随着GPT-4、Claude 3等大模型的普及,AI原生应用(从设计之初就以AI为核心的应用)正从“概念”走向“落地”。依赖大量外部API的协同工作(如用户身份API→大模型生成API→支付API→存储API)。但随之而来的挑战是:如何在复杂的API调用链中,确保每个环节的权限合规?本文将聚焦这一问题,覆盖API编排的基础逻辑、权限管理的核心机制(如RBAC/ABAC)、实战工具链(如OPA策略引擎),以及常见场景的解决方案。本文将按照“场景引入→核心概念→原理拆解→实战演练→趋势展望”的逻辑展开。

大数据洞察的博客 451

超硬核实操!DeepSeek 全方位赋能嵌入式工程师,干货满满

摘要:本文聚焦 DeepSeek 大语言模型在嵌入式开发中的实操应用。开篇阐述其在开发前期助工程师精准理解需求、规划架构;代码编写阶段,可生成补全代码、助力算法实现与优化;调试测试时,能定位问题、生成测试用例;学习阶段,帮整理资料、规划学习路径。文中借助 Python 实现与模型交互,提供大量实操流程与代码示例。虽存在不足,但实操彰显其巨大潜力,为嵌入式工程师提供高效工作新思路与全面实操指南。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 2001

Java之同步锁synchronized实例讲解

线程安全概念:当多个线程访问一个类(对象或方法)时,这个类始终都能表现出正确的行为,那么这个类(对象或方法)就是线程安全的。 1.可以在任意对象及方法上加锁,而加锁的这段代码称为"互斥区"或"临界区" 2.一般状况下,关键字synchronized取得的锁都是对象锁,而不是把一段代码(方法)当作锁。 3.在静态方法上加上synchronized关键字,表示锁定.class类(或者 synchro...

玻璃汽水的博客 1261

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

用synchronized就一定线程安全吗?

这篇文章是小编观看一位阿里java高级工程师的文章,由此转载过来的,大家看完觉得不错的话,可以根据文章最后图片上的微信好加他好友,或者关注作者的公众号。 用synchronized对方法进行同步,还真不一定线程安全,来看个简单的例子 上面的代码运行出来的结果: 看到没,并不是2000000,那么为什么f1和f3方法都用了synchronized关键字,然而并没有达到我们需要的结果...

qq_41908272的博客 3206

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

你以为用synchronized就一定线程安全吗?

用synchronized对方法进行同步,还真不一定线程安全,来看个简单的例子 上面的代码运行出来的结果: 看到没,并不是2000000,那么为什么f1和f3方法都用了synchronized关键字,然而并没有达到我们需要的结果呢?这需要从synchronized的原理开始讲起。 synchronized关键字有下面三种用法: 修饰实例方法:对当前实例加锁,进入方法需要获...

1707

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

除了Synchronized,还能怎么保证线程安全

Lock 和 ReadWriteLock,主要实现类分别为 ReentrantLock 和 ReentrantReadWriteLock atomic 原子性+1 threadlocal 注意复杂对象及集合的clear,防止内存溢出 volatile 内存可见(不要将volatile用在getAndOperate场合(这种场合不原子,需要再加锁),仅仅set或者get的场景是适合volatile的) 可重入读写锁 ReentrantReadWriteLock(1、只有一个线程可以获取到写锁。在获

yangcai11的博客 1904

【JavaEE初阶 — 多线程】线程安全问题 & synchronized

【JavaEE初阶 — 多线程】线程安全问题 & Synchronized 观察线程安全问题,分析了造成线程安全问题造成的三个原因:线程的随机调度,多个线程修改共享数据(修改同一个变量),以及原子性问题,并讲述了如何解决这三种原因引发的线程不安全;并讲述了 synchronized 互斥 和 可重入 的特性,并给出了 synchronized的使用案例;简单介绍了Java标准库中的线程安全类和线程不安全类。

OuO-1 的博客 1282

【Java】synchronized 基础线程安全

Java 提供了多种机制来处理线程安全问题,其中关键字是最常用和最基础的一种。本文将介绍线程安全问题的原因,并解释关键字如何帮助解决这些问题。线程安全问题通常发生在多个线程同时访问和修改共享数据时,如果没有适当的同步机制,就可能导致数据不一致、程序崩溃或其他不可预测的行为。

高耳机的博客 586

Synchronized和线程安全

线程安全问题 什么是线程安全 多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能访问知道该线程读取完后,其他线程才可以使用出现数据不一致或者数据污染 线程不安全 线程不安全就是不提供数据的访问保护,有可能出现多个线程更改数据造成所得到的数据时脏数据(引用自http://blog.youkuaiyun.com/ghevinn/article/details/37764791/

xiaopioo的博客 403

Java synchronized 以及线程安全

Java synchronized 以及线程安全

kuroshiro的博客 1375

用synchronized就一定线程安全吗?

用synchronized对方法进行同步,还真不一定线程安全。   这需要从synchronized的原理开始讲起。synchronized关键字有下面三种用法:   修饰实例方法:     对当前实例加锁,进入方法需要获得当前实例的锁修饰静态方法:     对当前类对象加锁,进入静态方法需要获得当前类对象的锁修饰代码块:     对指定对象进行加锁,进入代码块需要获得指定对象的锁...

weixin_30488313的博客 509

线程安全处理Synchronized

线程安全处理Synchronized 开发工具与关键技术:eclipse java 作者:梁峻豪 线程同步(线程安全处理 Synchronized) java 中提供了线程同步机制,它能够解决上述的线程安全问题。 线程同步的方式有两种: 方式 1:同步代码块 方式 2:同步方法 (1)同步代码块: 同步代码块: 在代码块声明上 加上 synchronized synchronized (锁对象) { 可能会产生线程安全问题的代码 } 同步代码块中的锁对象可以是任意的对象; 但多个线程时,要使用同一个锁对

Gksjn的博客 3928

线程安全——synchronized

基本概念: 线程安全概念:当多个线程访问某一个类(对象或方法)时,这个类始终都能表现 出正确的行为,那么这个类(对象或方法)就是线程安全的。 synchronized:可以在任意对象及方法上加锁,而加锁的这段代码称为“互斥区”或 “临界区”。 当多个线程访问myThread的run方法时,以排队的方式进行处理(这里排对是按照CPU 分配的先后顺序而定的),一个线程想要执行synchronized修饰的方法里的代码,首 先是尝试获得锁,如果拿到锁,执行synchronized代码体

qq_39246466的博客 564

线程安全(synchronized、volatile)

线程安全是多线程编程中的一个概念。在多个线程同时对某个资源进行操作时,线程安全的代码会通过同步机制保证多个线程的运行是正常且正确的,不出现数据污染等意外情况(或者说在多线程中运行代码的结果与在单线程中运行的结果一致时,可以认为是线程安全的)。wait 和 notify 的四种方法都是 Object 的方法。wait 需要搭配锁使用,sleep 不做要求;

哈哈哈哈的博客 717

Thread之线程安全、ThreadLocal和synchronized

线程安全问题指的是在多线程中,各线程之间因为同时操作所产生的数据污染或其他非预期的程序运行结果。

xiaotu的博客 344

线程安全和锁 Synchronized 概念

线程安全和锁 Synchronized 概念 进程(Process) 计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。 线程 有时被称为轻量级进程(Lightweight Pro...

qq_42969887的博客 297
上一篇: Nginx
下一篇: 工厂模式
l_learning
博客等级 码龄8年 15粉丝 82原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值