首页 > 其他分享 >关于线程安全的思考

关于线程安全的思考

时间:2023-05-02 21:46:28浏览次数:40  
标签:重入 同步 Java synchronized 安全 线程 思考 数据

线程安全是什么?

维基百科:线程安全程序设计中的术语,指某个函数函数库多线程环境中被调用时,能够正确地处理多个线程之间的公用变量,使程序功能正确完成。

《Java并发编程实战(Java Concurrency In Practice)》的作者Brian Goetz:当多个线程同时访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那就称这个对象是线程安全的。”

实现线程安全的几种方式

同步的定义:同步是指在多线程环境中,控制多个线程

阻塞同步(悲观)

互斥是方法是手段,同步是目的。

使用

 

synchronized和ReentrantLock对比:

  • Java语法层面的同步,足够清晰,也足够简单;

  • 对开发者要求高,必须要在finally块中释放锁;

  • JVM可以在线程和对象的元数据中记录synchronized中锁的相关信息来进行优化,而Lock不行。

    如果synchronized能满足使用需求那就使用synchronized。

     

    ReentrantLock的高级功能:

    • 线程阻塞等待时可以中断;

    • 可以实现公平锁(在锁被释放时,等待锁的所有线程按照时间顺序来依次获得锁,性能差,吞吐量下降);

    • 锁可以绑定多个条件。

    •  

这是一种悲观的策略。不管共享数据有没有出现竞争,都会默认加上锁(不过JDK6下下的synchronized除外,JVM会通过线程和对象的元数据信息优化掉很大一部分不必要的加锁)。主要问题是进行

非阻塞同步(乐观无锁)

硬件层面提供的基于冲突检测的乐观并发策略,通俗地说就是不管共享数据有没竞争,直接操作;如果共享的数据的确出现竞争了,产生了冲突,那再进行其他的补偿措施,最常用的补偿措施是不断地重试,直到出现没有竞争的共享数据为止。

JDK下的Unsafe类中的native方法compareAndSwapInt,其中JUC下的AutomicInteger的incrementAndGet方法就使用到了。

无需同步

 

可重入代码的确具备上述特征,例如不依赖全局变量、存储在堆上的数据和公用的系统资源,用到的状态量都由参数中传入,不调用非可重入的方法等。因此,如果一个方法的返回结果是可以预测的,只要输入了相同的数据就都能返回相同的结果,那么它就满足可重入性的要求,即使这个方法被多个线程同时调用也不会出现线程安全问题。

可重入代码的另一个重要特征是,当一个线程在执行可重入代码时,它可以被另一个线程中断,并在中断后恢复执行,而不会影响程序的正确性。这是因为可重入代码只依赖于传入的参数和局部变量,它不会修改全局变量和其他线程共享的资源,因此不会对其他线程的执行产生影响。

总之,可重入代码具有预测性和可中断性两个特征,这些特征保证了可重入代码的线程安全性,使得它可以被多个线程同时调用而不会出现数据竞争、死锁等线程安全问题

 

把共享数据的代码保证在同一个线程中执行。

Java中的实现就是ThreadLocal。一般使用在存储用户数据上下文。

 

参考:《深入理解Java虚拟机》

标签:重入,同步,Java,synchronized,安全,线程,思考,数据
From: https://www.cnblogs.com/road2master/p/17368305.html

相关文章

  • 对多线程的一点理解
     电脑是8核的。 ......
  • 三、JVM-运行时数据区概述及线程(基础篇)
    一、前言本节主要讲的是运行时数据区,也就是下图这部分,它是在类加载完成后的阶段当我们通过前面的:类的加载->链接(验证->准备->解析->)->初始化这几个阶段完成后,就会用到执行引擎对我们的类进行使用,同时执行引擎将会使用到我们运行时数据区也就是大厨做饭,我们把大厨后......
  • 12 BTC-思考
    《区块链技术与应用》课程链接:https://www.bilibili.com/video/BV1Vt411X7JF/?spm_id_from=333.337.search-card.all.click12BTC-思考目录12BTC-思考哈希指针,比特币很多设计使用了hash指针,指针保存的只是本机的内存地址,发送到其他计算机上就没有意义,那么,在发布区块的时候,h......
  • 线程的创建和终止
     拥有线程程序的编译需要加-pthreadgcca.c-oa-pthread /*#include<pthread.h>intpthread_create(pthread_t*thread,constpthread_attr_t*attr,void*(*start_routine)(void*),void*arg);功......
  • Socks5协议与IP代理在网络安全中的应用
      在网络安全中,IP代理是一种重要的安全工具,它可以为用户提供匿名性和隐私保护,同时也可以保护用户免受网络攻击。而Socks5是IP代理中常用的一种协议,它具有高度的安全性和灵活性。在本文中,我们将介绍Socks5协议和IP代理的作用及其在网络安全中的应用。什么是IP代理?  IP代理是......
  • 使用Socks5代理在Windows上实现更安全的网络连接
    作为一名网络工程师,我们经常需要在不同的网络环境下工作,这可能会给我们的计算机安全带来一定的风险。使用Socks5代理是一种简单而有效的方式,可以在Windows操作系统上提高网络安全性,本文将介绍如何在Windows上设置和使用Socks5代理。什么是Socks5代理?Socks5代理是一种网络协议,它可以......
  • 如何避免单点风险:基于实践经验分享服务拆分原则的一些思考
    缘起:系统崩了具体情况:1%的请求影响了剩余90%的请求架构演进:拆分热点服务【进程级隔离】复盘总结拆服务的经典实践 不能变形的变形金刚也叫变形金刚?缘起系统崩溃了?别惊慌!这里有快速恢复的方法!分析发现,网站崩时服务X被流量打垮,继而依赖服务X的其它服务开始......
  • JAVA创建线程的方式总结
    1.继承Thread类通过继承Thread类,并重写它的run方法,就可以创建一个线程。publicclassTestThread1extendsThread{publicTestThread1(Stringname){super(name);}@Overridepublicvoidrun(){System.out.println(Thread.currentTh......
  • 线程池监控方案
    5ycode某信贷cto,专注于java技术研究与应用,包括JVM、DDD、软件设计、源码阅读、以及经验分享9篇原创内容公众号读了Java线程池实现原理及其在美团业务中的实践后,我就想一个问题,如果让我去做这个线程池的监控,我该怎么做?要对线程池进行监控,首先得明白,我们监控线程池的目的是什么?监控......
  • Java线程池中的四种拒绝策略
    CallerRunsPolicy:这是默认的拒绝策略,当线程池队列已满并且无法处理新任务时,将由提交任务的线程来执行该任务。这种策略可以降低新任务的流量,但也会增加提交任务的线程的负载。AbortPolicy:当线程池队列已满并且无法处理新任务时,将抛出RejectedExecutionException异常,阻止新任......