首页
学习
活动
专区
圈层
工具
发布
    • 综合排序
    • 最热优先
    • 最新优先
    时间不限
  • Java EE(8)——线程安全——策略&CAS

    ) 的常见类:ReentrantLock,原子类,Semaphore,CountDownLatch 4.线程安全的集合类:多线程环境使用 ArrayList/队列/哈希表 1.策略 1.1各种策略介绍 乐观&悲观 1.1.1乐观&悲观 乐观和悲观只是的一种策略,并不是具体实现 乐观: 假设冲突概率低,先操作,更新时检查数据有没有被修改过,比如用版本号机制。 1.1.3自旋&挂起等待 自旋是轻量级的具体实现,挂起等待是重量级的具体实现 自旋:自旋是一种忙等待的,当某线程尝试获取自旋时,如果该已经被其他线程持有,该线程不会陷入阻塞,而是会在一个循环中不断地检查是否被释放 这个过程涉及用户态和内核态的切换,线程的阻塞和唤醒,并且要保存该线程的上下文信息,会消耗性能,所以挂起等待是重量级的实现 1.1.4读写 多线程之间,数据的读取方之间不会产生线程安全问题,但数据的写入方互相之间以及和读者之间都需要进行互斥 当计数器为零时,才真正被释放 不可重入:线程已经持有某个对象的,那么它可以再次获取该对象的,会被阻塞 1.2其他策略 消除 编译器+JVM 判断是否可消除.。

    18110编辑于 2026-01-13
  • 来自专栏dcmickey小站

    8问题

    8问题 场景一 标准情况访问:两个同步方法,一个对象调用 import java.util.concurrent.TimeUnit; /** * 标准情况下 是先sendEmail() 还是先callPhone 两个方法持有的是同一把,因此谁先拿到谁先执行。 public class LockDemo8 { public static void main(String[] args) throws InterruptedException { Phone8 phoneA = new Phone8(); Phone8 phoneB = new Phone8(); new Thread(()->{ new Thread(()->{ phoneB.callPhone(); },"B").start(); } } class Phone8{

    46810编辑于 2022-06-09
  • 来自专栏JavaEdge

    线程安全优化1 线程安全2 优化

    1 线程安全 当多个线程访问一个对象时,如果不用考虑这些线程在运行环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那么这个对象是线程安全的 1.1 Java语言中的线程安全 按照线程安全的“安全程度”由强至弱来排序,我们可以将Java语言中各种操作共享的数据分为 不可变(Immutable) 不可变的对象一定是线程安全的。 满足线程安全 Java API中标注自己是线程安全的类,大多数都不是绝对线程安全的。 相对线程安全 就是我们通常意义上所讲的线程安全,需要保证对这个对象单独的操作是线程安全的,我们在调用的时候不需要做额外的保障措施,但是对于一些特定顺序的连续调用,就可能需要在调用端使用额外的同步手段来保证调用的正确性 线程兼容 对象本身并不是线程安全的,但是通过使用同步手段来保证对象在并发环境中可以安全的使用。

    1.1K90发布于 2018-05-16
  • 来自专栏solate 杂货铺

    go 安全map 实现, 互斥和读写

    互斥 其中Mutex为互斥,Lock()加锁,Unlock()解锁,使用Lock()加锁后,便不能再次对其进行加锁,直到利用Unlock()解锁对其解锁后,才能再次加锁.适用于读写不确定场景,即读写次数没有明显的区别 ,并且只允许只有一个读或者写的场景,所以该叶叫做全局. package main import ( "fmt" "sync" "errors" ) type MyMap struct { 读写即是针对于读写操作的互斥。 它与普通的互斥最大的不同就是,它可以分别针对读操作和写操作进行锁定和解锁操作。读写遵循的访问控制规则与互斥有所不同。 在读写管辖的范围内,它允许任意个读操作的同时进行。 也就是说,读写控制下的多个写操作之间都是互斥的,并且写操作与读操作之间也都是互斥的。但是,多个读操作之间却不存在互斥关系。

    5.4K20发布于 2019-07-22
  • 来自专栏技术面面观

    Go 并发安全

    ★ 并发安全,就是多个并发体在同一段时间内访问同一个共享数据,共享数据能被正确处理。” 个人建议只要涉及到共享变量统统使用channel,因为channel源码中使用了互斥,它是并发安全的。 我们可以不用,但不可以不了解,手中有粮心中不慌。 并发不安全的例子 数组是并发不安全的,在例子开始前我们要知道append函数的行为:长度足够在原数组cap内追加函数,增加len,长度不够则触发扩容,申请新数组cap增加一倍,赋值迁移。 ,在一个写获取时,其他所有都等待, 口诀:读读不互斥、读写互斥、写写互斥。 小结 学习了几个名词:临界区、竞态问题、互斥、原子操作、读写。 互斥:sync.Mutex, 读写:sync.RWMutex 都是 sync 包的。 读写比互斥效率高。

    65620编辑于 2023-03-02
  • 来自专栏花落的技术专栏

    线程安全优化

    概述 线程安全 当多个线程同时访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那就称这个对象是线程安全的 Java语言中的线程安全 Java语言中各种操作共享的数据分为以下五类:不可变、绝对线程安全、相对线程安全、线程兼容和线程对立。 不可变undefined在Java语言里面,不可变undefined(Immutable)的对象一定是线程安全的,无论是对象的方法实现还是方法的调用者,都不需要再进行任何线程安全保障措施。 绝对线程安全 相对线程安全undefined相对线程安全就是我们通常意义上所讲的线程安全,它需要保证对这个对象单次的操作是线程安全的,我们在调用的时候不需要进行额外的保障措施,但是对于一些特定顺序的连续调用 线程兼容 线程对立 线程安全的实现方法 互斥同步undefined互斥同步(Mutual Exclusion & Synchronization)是一种最常见也是最主要的并发正确性保障手段。

    58920编辑于 2021-12-15
  • 来自专栏全栈程序员必看

    MySQL的机制_线程安全机制

    这里写目录标题 一、前言 二、的类型 2.1 全局 2.2 表级 2.2.1 表 2.2.2 元数据(Meta Data Locks) 2.2.3 自增列(AUTO-INC Locks) 2.2.4 保证表结构变更操作的安全性。 这种方式会大大提高AUTO_INCREMENT值插入的性能,但是也会带来的问题是——并发时事务的自增列值是不连续的,主从复制时可能是不安全的。 意向共享(IS):当事务准备给表记录加S时,需要先对表加上IS 意向排它 (IX) :当事务准备给表记录加X时,需要先对表加上IX 表级别的兼容性如下: 兼容性 S IS X IX 也就是说,IS和IX只是为了后续对表加S或者X时才起作用。 IS不兼容表级X,兼容表级S。意思是表中记录加了S的,只允许对表整体加S IX不兼容表级X和S

    1.1K20编辑于 2022-11-11
  • 来自专栏若尘的技术专栏

    线程安全优化

    线程安全 当多个线程同时访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那就称这个对象是线程安全的 Java语言中的线程安全 Java语言中各种操作共享的数据分为以下五类:不可变、绝对线程安全、相对线程安全、线程兼容和线程对立。 不可变undefined在Java语言里面,不可变undefined(Immutable)的对象一定是线程安全的,无论是对象的方法实现还是方法的调用者,都不需要再进行任何线程安全保障措施。 绝对线程安全 相对线程安全undefined相对线程安全就是我们通常意义上所讲的线程安全,它需要保证对这个对象单次的操作是线程安全的,我们在调用的时候不需要进行额外的保障措施,但是对于一些特定顺序的连续调用 线程兼容 线程对立 线程安全的实现方法 互斥同步undefined互斥同步(Mutual Exclusion & Synchronization)是一种最常见也是最主要的并发正确性保障手段。

    61864发布于 2021-11-21
  • 来自专栏Java那些事儿

    JUC学习之8现象

    8现象,其实就是关于的八个问题,本节我们通过八个问题,逐渐带大家加深对的认识,为了方便演示,这里全部用synchronized演示。 synchronized method -> 玩耍 synchronized method -> 吃饭 总结:synchronized的是方法的调用者,这里就是people1,不同的对象对应不同的 synchronized method-> 学习 static synchronized method-> 吃饭 问题8:不同对象调用1个静态同步方法,1个同步方法,先执行哪个?

    83030发布于 2020-07-21
  • 来自专栏全栈开发工程师

    【JUC】002-8现象

    到底的谁?要么new出来的对象,要么是Class,下面详解) (8就是关于8个问题) 一、问题1和2 1、问题 ①标准情况下,两个线程是先打印发短信还是打电话? 8:关于8个问题 * 1、标准情况下,两个线程是先打印发短信还是打电话? 2、代码、注释及运行结果 代码和注释: package com.zibo.lock8; import java.util.concurrent.TimeUnit; /** * 8:关于8个问题 2、代码、注释及运行结果 代码和注释: package com.zibo.lock8; import java.util.concurrent.TimeUnit; /** * 8:关于8个问题 2、代码、注释及运行结果 代码和注释: package com.zibo.lock8; import java.util.concurrent.TimeUnit; /** * 8:关于8个问题

    26200编辑于 2025-01-06
  • 来自专栏韩曙亮的移动开发专栏

    【Java 并发编程】线程机制 ( 线程安全 | 机制 | 类 | 对象 | 轻量级 | 重量级 )

    文章目录 一、线程安全 二、机制 ( 类 | 对象 ) 三、分类 ( 轻量级 | 重量级 ) 一、线程安全 ---- 多个线程同时访问 同一个共享变量 时 , 只要能保证 数据一致性 , 那么该变量是线程安全的 ; 这里的数据是指主内存中的共享变量以及各个线程中的变量副本 , 保证这些变量一致 , 就是线程安全 ; 线程安全 就是保证 线程操作的 原子性 , 可见性 , 有序性 ; volatile 关键字可以保证 可见性 与 有序性 ; synchronized 关键字可以保证 原子性 ; 二、机制 ( 类 | 对象 ) ---- synchronized 是 Java 提供的一种机制 ; 在普通方法上加锁 ( 轻量级 | 重量级 ) ---- 如果线程 A 获得之后 , 执行线程内容 , 其它线程等待解锁时有两种情况 : 轻量级 : 又称为 自旋 , 线程 盲等待 或 自旋等待 , 即 while 一旦涉及到操作系统 , 量级就变重 , 效率变低 ; ( 重量级 ) 轻量级弊端 : 轻量级 不一定 比重量级 更好 ; 轻量级 等待过程中 , 高速执行循环代码 , 如果循环的时间很短 ,

    1.7K20编辑于 2023-03-29
  • 来自专栏苏三说技术

    MySQL中的 8

    这篇文章跟大家一起聊聊MySQL的8,希望对你会有所帮助。 一、的本质:并发控制的基石 1.1 为什么需要? 二、的分类全景图 2.1 按粒度划分 按粒度划分为: 表 2.2 按模式划分 类型 共享性 典型场景 共享(S) 可共享 SELECT ... LOCK IN SHARE MODE 排他(X) 独占 UPDATE/DELETE/INSERT 意向共享(IS) 表级标记 准备加行级S前 意向排他(IX) 表级标记 准备加行级X前 三、 工具 总结 是双刃剑:保护数据一致性的同时降低并发度 粒度决定性能:行 > 页 > 表 隔离级别是基础:根据业务选择合适级别(推荐RR) 索引是钥匙:80%的问题可通过优化索引解决 监控是眼睛 最高明的策略是“无”,而这正是我们不断优化的方向。

    89210编辑于 2025-07-16
  • 来自专栏AustinDatabases

    MYSQL 8 备份数据库 新

    FTWRL 对于备份的意义在于,在我们操作这个命令的时候,会获取每个表的metadata lock , 此时获取表的lock 是逐步的过程,必须等待每个表的事务完成后,才能获得表元数据,并将的模式锁定到共享 实际上 FTWRL 做了以下几个工作 1 对所有的表上了全局的读, 2 清理了表缓存 3 上全局commit. 总结FTWRL ,几个步骤, 请求, 等待, 刷新表,持有.而我们今天要说的mysql 8.0 的LOCK INSTANCE FOR BACKUP 新特色, 其实在 PERCONA 5.6 版本的 "旧" 官方文档中对LOCK INSTANCE FOR BACKUP 获得一个instance level 的backup lock , 可以在持有时进行DML 操作. 所以MYSQL 8 新备份的方式的改变是通过LOCK INSTANCE for BACKUP 和 log_status 联合完成的, 基于MYSQL 8 的第三方备份软件等都需要对此进行研究并改变目前的备份的方式

    2.3K40发布于 2021-07-15
  • 来自专栏腾讯云智能·AI公有云

    筑牢金融自主安全

    以其中的一闪活体检测为例,在银河麒麟操作系统测试中表现为: 测试结果 1)中安全模式下,攻击拦截率达到98.5%; 2)高安全模式下,攻击拦截率达到99.9%。 一直以来,金融安全都面临三大挑战:业务安全、技术安全和监管安全。 随着数字技术与金融业进一步融合发展,带来金融服务业态新变革的同时,也不可避免地产生网络攻击、欺诈等各类安全风险。 可以针对性解决银行、保险、券商、运营商等金融行业面临的身份核验安全问题。 腾讯云慧眼私有化服务在国产CPU和国产操作系统测试的成功运行,为金融行业客户增加了自主可控的“安全”。 未来,腾讯云AI将持续扮演产业安全的“好助手”,助力产业实现安全可靠的业务保障。 在业务方案安全层面,腾讯云AI将在金融风控、反欺诈等方面持续展开深入研究,构建多重验证的金融安全通道;在底层技术安全方面,基于腾讯的安全技术积累,腾讯云AI将提供更加领先的技术服务。

    1.4K30编辑于 2022-04-07
  • 来自专栏Java开发必知必会

    图解Janusgraph系列-并发安全:Lock机制(本地+分布式)分析

    图解Janusgraph系列-并发安全机制(本地+分布式)分析 大家好,我是洋仔,JanusGraph图解系列文章,实时更新~ 图数据库文章总目录: 整理所有图相关文章,请移步(超链):图数据库系列 :洋仔聊编程 微信公众号:匠心Java 原文地址:https://liyangyang.blog.csdn.net/ 在分布式系统中,难免涉及到对同一数据的并发操作,如何保证分布式系统中数据的并发安全呢 一:分布式 常用的分布式实现方式有三种: 1、基于数据库实现分布式 ​ 针对于数据库实现的分布式,如mysql使用使用for update共同竞争一个行来实现; 在JanusGraph中,也是基于数据库实现的分布式 ,主要目的: 在图实例维度来做一层判断,减少分布式的并发冲突,减少分布式带来的性能消耗 2.4 分布式 在本地获取成功之后才会去尝试获取分布式; 分布式的获取整体分为两部分流程: 分布式信息插入 ,数据导入开销非常大;如果是数据不是要求很高的一致性,并且数据量比较大,我们可以选择关闭分布式锁相关,来提高导入速度; 然后,针对于小数据量的要求高一致性的数据,单独开启分布式来保证数据安全; 另外,

    81020编辑于 2022-05-11
  • 来自专栏Miigon's Blog

    笔记 Lab8: Locks | 优化

    Lab 8: Locks 重新设计代码以降低竞争,提高多核机器上系统的并行性。 此时我们对 b 进行驱逐就是不安全的了。 解决方法也并不复杂,只需要在扫描桶的时候,确保找到最近最久未使用的空闲 buf 后,不释放桶,继续持有其对应的桶的直到驱逐完成即可。 这里不得不承认,我并没有想到什么特别好的方法,只想到了一个牺牲一点效率,但是能保证极端情况下安全的方案: 添加 eviction_lock,将驱逐+重分配的过程限制为单线程 注意此处应该先释放桶后,再获取 // 这里由于持有 eviction_lock,没有任何其他线程能够进行驱逐操作,所以 // 没有任何其他线程能够改变 bufmap[key] 桶链表的结构,所以这里不事先获取 // 其相应桶而直接开始遍历是安全的 所以拿着 eviction_lock 的时候,可以安全遍历每个桶的每个节点,但是不能访问 refcnt。

    1.2K10编辑于 2022-10-27
  • Go语言map并发安全,互斥和读写谁更优?

    互斥(Mutex)互斥是最基本、最直接的并发原语之一,它保证了在任何时刻只有一个 goroutine 能对数据进行操作,从而保证了并发安全。 需要确保数据写操作的绝对安全,且读操作不远远高于写操作。缺点读操作多于写操作时,效率较低,因为读操作也会被阻塞。读写(RWMutex)读写维护了两个状态:读状态和写状态。 当一个 goroutine 获取读时,其他 goroutine 仍然可以获取读,但是写会被阻塞;当一个 goroutine 获取写时,则所有的读和写都会被阻塞。 读的请求会在没有写操作或写请求时获得满足,写的请求则需要等待所有的读和写释放。适用场景读操作远多于写操作。读操作需要较高性能,而写操作频率较低。 反之,如果读写操作频率相似,或者写操作的安全性至关重要,那么使用 sync.Mutex 会更加简单和直接。理解每种的内部实现和特点,可以帮助我们更加精细地控制并发,提升程序的性能和稳定性。

    46210编辑于 2024-07-12
  • 来自专栏运维博客

    Go语言入门(八)线程安全&

    线程安全& 定时器&一次性定时器 定时器 func main() { ticker := time.NewTicker(time.Second) //ticker.C是一个只读的chan, hello") }() var i int for { fmt.Printf("%d\n",i) time.Sleep(time.Second) } } 线程安全 典型的例子 多个goroutine同时操守做一个资源,这个资源叫做临界区 现实生活中的十字路口,通过红绿灯来实现线程安全 火车上卫生间,通过互斥实现线程安全 实际例子: x=x+1 先从内存中取出 同时且只有一个线程进入临界区,其他的线程则在等待 当互斥释放之后,等待的线程才可以获取进入临界区 多个线程同时等待同一个,唤醒的策略是随机的 修复线程问题,使其正确输出 var count int 使用场景: 读多写少的场景 分为两种角色: 读和写 当一个goroutine获取写之后,其他的goroutine获取写或读都会等待 当一个goroutine获取读之后,其他的goroutine

    58810发布于 2020-09-24
  • 来自专栏Java编程技术

    JDK8并发包新增StampedLock

    4.8 JDK8新增的StampedLock探究 StampedLock是并发包里面jdk8版本新增的一个,该提供了三种模式的读写控制,三种模式分别如下: 写writeLock,是个排它或者叫独占 ,同时只有一个线程可以获取该,当一个线程获取该后,其它请求的线程必须等待,当目前没有线程持有读或者写的时候才可以获取到该,请求该成功后会返回一个stamp票据变量用来表示该的版本,当释放该时候需要 悲观读readLock,是个共享,在没有线程获取独占写的情况下,同时多个线程可以获取该,如果已经有线程持有写,其他线程请求获取该读会被阻塞。 下面通过JDK8注释里面的一个例子讲解来加深对上面讲解的理解。 代码(1)获取悲观读,保证其它线程不能获取写修改x,y值,然后代码(2)判断如果当前点在原点则更新坐标,代码(3)尝试升级读为写,这里升级不一定成功,因为多个线程都可以同时获取悲观读,当多个线程都执行到

    58510发布于 2018-09-06
  • 来自专栏学习计划

    多线程8 读写ReentrantReadWriteLock加解锁

    不可以升级,写可以降级? 读是可并行的,写是串行的,那么如果多个读并行执行,遇到升级语句,就会出现死锁,比如t1要升级,那么就要等t2释放,而t2正好也在当t1释放。 =0,表示重入;这里有两种:读,写 if (c ! ,重入+1 setState(c + acquires); return true; } // 走到这里,表示c=0,即没有写,也没有读 if (writerShouldBlock 因为在读加锁的时候,也可能出现写进来,如果写进来了,写是排他,独占一把,那么读也要去排队 if (exclusiveCount(c) ! 因为在读加锁的时候,也可能出现写进来,如果写进来了,写是排他,独占一把,那么读也要去排队 if (exclusiveCount(c) !

    69210发布于 2021-01-29
领券