线程安全

C++线程安全函数 标准库函数:如std::coutstd::mutex等。互斥锁:通过std::mutex保护共享资源。原子操作:使用避免数据竞争。条件变量:通过实现线程同步。线程安全容器:手动加锁保护标准库容器。单例模式:使用双重检查锁定或实现线程安全的单例。根据具体需求选择合适的方式,可以实现高效、安全的并发编程。 阅读详情

线程安全

什么是线程安全?

为什么有线程安全问题?

当多个线程同时共享,同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题。但是做读操作是不会发生数据冲突问题。

 

案例: 现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果。

package com.toov5.threadSecurity;

public class TrainThread implements Runnable{
     private int trainCount = 100;
    
       @Override
    public void run() {
        while(trainCount>0){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            sale();
        }
        
    }
       
    public void sale(){
        if(trainCount>0){
            System.out.println(Thread.currentThread().getName()+",出售第"+(100-trainCount+1)+"张票");
            trainCount--;
        }
    
    }   
       
       
    public static void main(String[] args) {
        TrainThread trainThread = new TrainThread();
        Thread t1 = new Thread(trainThread,"1号窗口");
        Thread t2 =    new Thread(trainThread,"2号窗口");
        t1.start();
        t2.start();
    }   
       
    
}

 

 

 代码运行结果是有问题的

 

 

一号窗口和二号窗口同时出售火车第九九张,部分火车票会重复出售。

结论发现,多个线程共享同一个全局成员变量时,做写的操作可能会发生数据冲突问题。

 

线程安全解决办法:

1、使用多线程之间同步synchronized或使用锁(lock)解决多线程之间的安全问题

     将可能会发生数据冲突问题(线程不安全问题),只能让当前一个线程进行执行。代码执行完成后释放锁,让后才能让其他线程进行执行。这样的话就可以解决线程不安全问题。

2、当多个线程共享同一个资源,不会受到其他线程的干扰,这就是多线程之间的同步问题

 

 

内置的锁

Java提供了一种内置的锁机制来支持原子性

每一个Java对象都可以用作一个实现同步的锁,称为内置锁,线程进入同步代码块之前自动获取到锁,代码块执行完成正常退出或代码块中抛出异常退出时会释放掉锁

内置锁为互斥锁,即线程A获取到锁后,线程B阻塞直到线程A释放锁,线程B才能获取到同一个锁

内置锁使用synchronized关键字实现,synchronized关键字有两种用法:

1.修饰需要进行同步的方法(所有访问状态变量的方法都必须进行同步),此时充当锁的对象为调用同步方法的对象

2.同步代码块和直接使用synchronized修饰需要同步的方法是一样的,但是锁的粒度可以更细,并且充当锁的对象不一定是this,也可以是其它对象,所以使用起来更加灵活

 

同步代码块synchronized

就是将可能会发生线程安全问题的代码,给包括起来。

synchronized(同一个数据){

 可能会发生线程冲突问题

}

就是同步代码块 

synchronized(对象)//这个对象可以为任意对象 

{ 

    需要被同步的代码 

} 

对象如同锁,持有锁的线程可以在同步中执行 

没持有锁的线程即使获取CPU的执行权,也进不去 

同步的前提: 

1,必须要有两个或者两个以上的线程 

2,必须是多个线程使用同一个锁 

必须保证同步中只能有一个线程在运行 

好处:解决了多线程的安全问题 

弊端:多个线程需要判断锁,较为消耗资源、抢锁的资源。 

比如本demo:

public void sale(){
        synchronized (this) {
            if(trainCount>0){
                System.out.println(Thread.currentThread().getName()+",出售第"+(100-trainCount+1)+"张票");
                trainCount--;
            }
        }
    }   
public void sale(){
        synchronized (obj) {
            if(trainCount>0){
                System.out.println(Thread.currentThread().getName()+",出售第"+(100-trainCount+1)+"张票");
                trainCount--;
            }
        }
    }   

 

同步方法

什么是同步方法?

在方法上修饰synchronized 称为同步方法

  public synchronized void sale(){
                if(trainCount>0){
                    System.out.println(Thread.currentThread().getName()+",出售第"+(100-trainCount+1)+"张票");
                    trainCount--;
            }
        }  

 

需要值得一提的是:

同步方法使用的是什么锁

证明方式: 一个线程使用同步代码块(this明锁),另一个线程使用同步函数。如果两个线程抢票不能实现同步,那么会出现数据错误。

哈哈哈,代码证明题,堪比数学题:

 思路: 另个线程共享操作同一个全局变量,每个线程锁不同。

一个使用非静态同步方法,另一个使用同步代码块

对于synchronize的写法我感觉真心像个 排列组合

代码块随便加 

方法(){

代码块(this)

 {

       }

}

等等

使用的时候尽量使用同步方法代码块哈 这样粒度更小一些 效率更高

证明代码

package com.toov5.threadSecurity;
class Thread02 implements Runnable{

    private int countTicket = 100;
    private static Object obj = new Object();

    public static  boolean flag = true;
    @Override
    public void run() {

        if(flag){//使用同步锁--this
            while(countTicket>0){
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sale1();
            }
        }else{//使用同步函数
            while(countTicket>0){
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sale();
            }
        }

    }

    public void sale1(){

        synchronized(obj){
            if(countTicket>0){ //------当把这个if判断去掉 最后还是会有两个线程来争夺最后一张票 会挨个执行,数据不会出错,但是逻辑会出错。
            System.out.println("当前线程名字:"+Thread.currentThread().getName()+";出售第"+(100 - countTicket + 1)+"张票。");
            countTicket--;
         }
        }
    }

    public synchronized void sale(){

        if(countTicket>0){
            //卖票
            System.out.println("当前线程名字:"+Thread.currentThread().getName()+";出售第"+(100 - countTicket + 1)+"张票。");
            countTicket--;
        }

    }
}

public class ThreadDemo1 {

    public static void main(String[] args) throws InterruptedException {
        Thread02 t = new Thread02();

        Thread t1 = new Thread(t,"窗口1");
        Thread t2 = new Thread(t,"窗口2");
        t1.start();
        Thread.sleep(50);
        Thread02.flag=false;
        t2.start();
    }

}

 

 两个线程,共享一个全局变量。每个锁不同

一个使用非静态同步代码块,一个使用同步代码块(this可以同步,Object不可以)

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2018-10-21 21:44 toov5 阅读( ...) 评论( ...) 编辑 收藏
车载以太网入坑指南,从小白到懂哥的进阶之路【技术分享】 各位技术大佬们好!最近公司项目涉及到车载以太网,刚开始完全懵逼,花了大半个月时间各种查资料、测试设备,总算是摸清了门道。想着互联网上卧虎藏龙,肯定有不少大佬对这个技术感兴趣,所以写个帖子分享一下,顺便求各位大佬指点。 阅读详情

相关推荐

解决Calibre中license的错误

本次解决了Calibre在Cadence 617 virtuoso版本中运行不了的错误,在遇到问题的时候,我也跟你们一样,首先是上网查询为什么运行不了呢?明明我安装了之后里面有Calibre的,我当时也是这样的疑惑,一点Calibre运行LVS的时候,一片空白,然后就出现了license的错误,后来点点点,看看看,搜搜搜,最终解决了这个问题。虚拟机是VMware16版本,cadence617,Calibre是2015版本。旨在记录遇到的实际问题。

yytu231的博客 1万+

除了加锁,还有什么方法解决资源竞争的问题?

我能想到的有三种方式:1)原子操作。2)副本。如ThreadLocal、CopyOnWrite等。3)不可变。

varyall的专栏 2544

A股量化实战:用Python回测动量因子策略(附聚宽完整代码)

本文详细介绍了如何在A股市场使用Python和聚宽平台,实战回测一个动量因子量化交易策略。从环境搭建、数据获取到完整的策略代码实现与回测分析,手把手教你验证“强者恒强”的投资逻辑,并提供参数优化与实战避坑指南,助力量化新手迈出第一步。

weixin_29264201的博客 969

什么是线程安全?

线程安全 “线程安全”的定义: 当多个线程同时访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那就称这个对象时线程安全的。 该定义要求线程安全的代码都必须具备一个共同特征: 代码本身封装了所有必要的正确性保障手段(如互斥同步等),令调用者无须关心多线程下的调用问题,更无须自己实现任何措施来保证多线程环境下的正确调用。 java语言中的线程安全 线程安全,将以多个线程之间存在共享数据访问

贾欣晓的博客 2万+

QGroundControl高级配置与自定义功能实战指南

本文深入探讨了QGroundControl(QGC)的高级配置与自定义功能,为无人机开发者、系统集成商和高级用户提供实战指南。内容涵盖从品牌界面定制、自定义MAVLink消息处理,到插件开发与自动化部署的全流程,旨在帮助用户解锁QGC的隐藏潜力,打造专属的行业解决方案。

weixin_29234509的博客 239

5G射频设计中N77&N79的PRX为什么需要3个SRS

首先,我们来逐个拆解一下这个神秘的“

weixin_43199439的博客 1324

JAVA中的线程安全与非线程安全

原文:http://blog.youkuaiyun.com/xiao__gui/article/details/8934832ArrayList和Vector有什么区别?HashMap和HashTable有什么区别?StringBuilder和StringBuffer有什么区别?这些都是Java面试中常见的基础问题。面对这样的问题,回答是:ArrayList是非线程安全的,Vector是线程安全的;HashMa

一只程序猿 2万+

高通 vs MTK vs 海思:三大平台 ISP 架构横向对比与实战差异分析

随着移动影像能力成为智能终端差异化竞争的核心维度,ISP(Image Signal Processor)架构日益重要。高通、MTK、海思三大 SoC 厂商在 ISP 设计上各具特色,不仅在图像处理链路、模块集成度、算法加速路径等方面存在显著差异,同时也决定了终端厂商在成像质量、调试复杂度与扩展能力上的实际表现。本文将基于真实平台项目经验,横向对比三大主流平台的 ISP 架构关键指标,系统分析其在实际开发过程中的能力边界、工程成本与调优空间,帮助工程师更精准地进行平台选型与优化策略制定。

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 3932

线程安全与非线程安全的区别

线程安全:是多线程访问时,采用加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。 非线程安全:是多线程访问时,不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。所得数据可能不一致 区别:非线程安全是指多线程操作同一个对象可能会出现问题。而线程安全则是多线程操作同一个对象不会有问题......

UserGuan的博客 5607

YOLO 系列专栏(二十九)YOLO26 × StarNet 轻量化涨点方案(CVPR 2024)轻量化、主干改进篇 | 星星卷积虽小,却蕴藏着巨大的高效潜力

StarNet 出自 CVPR 2024 轻量化主干网络工作,核心创新是,依靠逐元素乘法实现高阶特征融合,在几乎不增加参数量与 FLOPs 的前提下,大幅提升特征表达能力,天然适合等多任务统一建模。本文将 StarNet 完整替换 YOLO26 原有主干,保留 YOLO26 无 NMS 检测头与轻量化结构,实现,并提供。

qq_36130719的博客 410

Python爬虫教程:抓取短视频平台数据(以抖音和快手为例)

为什么抓取短视频平台数据?内容分析:通过抓取短视频平台上的视频内容、标题、标签等数据,可以进行内容分类、趋势分析、话题分析等。情感分析:抓取视频的评论数据,并进行情感分析,帮助企业或组织了解公众的情绪反馈。用户行为分析市场监测:通过抓取特定关键词或标签下的视频数据,分析市场趋势,进行竞争对手分析。短视频平台数据类型:视频信息:包括视频标题、描述、标签、作者等。用户信息:包括用户的昵称、粉丝数、关注数等。互动数据评论数据:视频下的用户评论内容及用户信息。

2201_76125261的博客 3662

什么是线程安全问题 及怎么解决线程安全问题

1.什么是线程安全问题 就是 多线程环境中 , 且存在数据共享 , 一个线程访问的共享 数据被其他线程修改了, 那么就发生了线程安全问题 , 整个访问过程中 , 无一共享的数据被其他线程修改了 就是线程安全的 程序中如果使用成员变量, 且对成员变量进行数据修改 , 就存在数据共享问题, 也就是线程安全问题 2.为什么会有线程安全问题? 当多个线程同时共享一个全局变量,或者静态变量, 进行写的操作时, 可能会发生数据的冲突问题 ,也就是线程安全问题, 但是做读的操作不会引发线程安全问题 线程安全 指多个线程在

恩琪 1万+

39、高频 LLC 谐振转换控制系统动态优化算法分析与研究

本文针对高频下LLC谐振转换器动态性能差的问题,提出一种基于谐振电容器充放电估计动态切换时间的优化控制算法。通过改进状态轨迹控制方法,突破传统算法在谐振频率与开关频率相等条件下的限制,并结合新型采样策略有效抑制电压过冲。算法在MATLAB和SABER中完成仿真验证,并搭建基于STM32F407的原型系统进行测试,结果表明该方法显著缩短动态响应时间,提升系统稳定性。研究为高频、高功率密度开关电源的动态优化提供了可行解决方案。

linux6sysadmin的博客 111

Java集合中那些类是线程安全的

线程安全类 在集合框架中,有些类是线程安全的,这些都是jdk1.1中的出现的。在jdk1.2之后,就出现许许多多非线程安全的类。 下面是这些线程安全的同步的类: vector:就比arraylist多了个同步化机制(线程安全),因为效率较低,现在已经不太建议使用。在web应用中,特别是前台页面,往往效率(页面响应速度)是优先考虑的。 statck:堆栈类,先进后出 hashtable:就比

Mexican的博客 10万+

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

什么是线程安全

线程安全是指在多线程环境中,当多个线程访问共享资源时,能够保证程序执行的正确性。如果一个代码片段在多线程下执行的结果与单线程下执行的结果相同,那么我们称这段代码是线程安全的。

weixin_73687229的博客 1325

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

什么是线程安全?一文搞懂线程安全的本质

官方定义:当多个线程同时访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象就是线程安全的。通俗理解:多个线程同时操作同一个数据,最终得到的结果和预期一致,就是线程安全的。线程安全的本质:多线程环境下,程序的行为符合预期问题根源:共享可变数据 + 并发访问 + 至少一个写操作实现方式不可变对象(最推荐)互斥同步(synchronized、Lock)非阻塞同步(Atomic类)

m0_62910542的博客 1435

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

一文教会你什么线程安全以及如何实现线程安全

title: 一文教会你什么线程安全以及如何实现线程安全 tags: 线程安全 Java并发 Java内存模型 synchronized volatile Lock 文章目录一、线程安全的概念二、导致线程不安全的原因三、线程安全问题3.1 原子性3.2 可见性3.3 有序性案例:抢票四、如何确保线程安全?4.1 synchronized关键字4.1.1 同步代码块4.1.2 同步函数4.1.3 多线程死锁线程4.2 Lock4.3 volatile关键字解决办法:4.4 synchronized、vol.

qq_39350172的博客 2756

什么是线程安全?Servlet 是线程安全的吗?

线程安全是指在多线程环境下访问共享资源时,系统的行为能够保持一致性和正确性。换句话说,当多个线程同时访问或修改同一个对象时,线程安全保证这些线程的执行不会导致数据的不一致性或产生意料之外的结果。在 Java 中,线程安全同步(Synchronization):通过加锁的方式确保同一时刻只有一个线程可以访问共享资源。不可变性(Immutability):通过将对象设计为不可变(即一旦创建,内部状态不能被修改),来保证线程安全。局部变量。

lssffy的博客 1036

Java 什么是线程安全及如何实现线程安全

通过 JVM 内置锁(Monitor)实现互斥访问,确保同一时间只有一个线程执行临界区代码。:基于 CAS(Compare-and-Swap)实现无锁线程安全操作,适用于简单原子操作。理解线程安全的三要素(原子性、可见性、有序性)是解决多线程问题的关键。死锁(Deadlock):多个线程互相等待对方释放锁,导致永久阻塞。:保证变量的可见性和禁止指令重排序,但不保证原子性。:操作不可分割,要么全部完成,要么全部不执行。更灵活的锁控制(如可中断、超时、公平锁)。单一变量的原子操作(如计数器、标志位)。

m0_37145844的博客 2121

在Java中什么时候才要考虑线程安全

点击蓝字关注我们本文字数:978字阅读时间:3分钟★什么是线程安全?★线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行...

AlbertYang的博客 4391

线程安全问题?怎么解决线程安全

一、线程安全等级 之前的博客中已有所提及“线程安全”问题,一般我们常说某某类是线程安全的,某某是非线程安全的。其实线程安全并不是一个“非黑即白”单项选择题。按照“线程安全”的安全程度由强到弱来排序,我们可以将java语言中各种操作共享的数据分为以下5类:不可变、绝对线程安全、相...

chushouxiu0552的博客 1684

线程安全问题

线程安全是指在多线程环境下,对于同一个对象的多个线程同时访问时,不会出现数据不一致、不可预测的结果。具体来说,线程安全要求程序在多线程并发执行时能够正确地处理共享资源的访问和操作,保证数据的一致性和正确性。原子性(Atomicity):对于多个线程并发访问同一个对象的某个操作,要么全部执行完毕,要么都不执行,中间不会被其他线程打断。可以使用锁(Lock)或原子操作(Atomic Operation)来保证原子性。

daweidi的博客 1271

线程安全的集合就一定线程安全吗?

土味情话:前半生到处浪荡,后半生为你煲汤。 前言 面试官:小伙子,你知道集合吗? 我:知道啊,集合的顶层接口为Collection,下面分为List、Set…(说的口水喷2m远) 面试官:好,你刚才说线程安全的集合,那线程安全的集合就一定线程安全吗? 我:线程安全的集合肯定线程安全啊(内心:???) 面试官:嗯,回去等通知吧 我:… So,线程安全的集合就一定线程安全吗? 集合简介 众所周知,集合分为线程安全和非线程安全,安全的集合有:List接口下的:Vector、CopyOnWriteArrayLi.

第一行代码 664

【Java 基础】HashMap 是线程安全的吗?那线程安全的 Map 有哪些?

HashMap 是非线程安全的,因为它不是同步的,多个线程同时对 HashMap 进行操作可能会导致数据不一致的问题。

激流丶的博客 2929

什么是线程安全? 如何保证线程安全?

随着硬件技术的快速发展(比如多核处理器,超线程技术),我们通常会在代码中使用多线程(比如线程池)来提高性能,但是,多线程又会带来线程安全问题。因此,本文将深入探讨Java中的线程安全问题。

weixin_42029738的博客 1181

什么是线程安全?如何在C#中实现线程安全?

线程安全(Thread Safety)是指程序在多线程环境中运行时,能够正确地访问和修改共享数据,避免出现竞态条件(Race Conditions)等问题。线程安全是多线程编程中的核心问题,C# 提供了丰富的工具和机制来确保线程安全。是一种简单且常用的线程同步机制,确保同一时刻只有一个线程可以执行被锁定的代码块。信号量用于限制线程的并发访问数量,例如控制一个资源最多被 N 个线程访问。适合读多写少的场景,允许多个线程同时读取,但只允许一个线程写入。是一种跨进程的同步机制,可以用来同步不同进程中的线程。

fapw15的博客 1681
上一篇: 多线程与Java的JMM内存模型
下一篇: 静态同步函数
Art&Code
博客等级 码龄7年 77粉丝 554原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值