1、一个对象是否是线程安全的,取决于它是否被多个线程访问。想要使得线程安全,需要通过同步机制来协同对对象可变状态的访问。

2、修复多线程访问可变状态变量出现的错误:1、程序间不共享状态变量 2、状态变量修改为不可变 3、使用同步

3、无状态的对象一定是线程安全的,一个类中如果没有包含任何域及其他类域的引用,则这个类是个无状态的类,类的对象是无状态对象。

4、线程安全下的一些概念:

  1、在并发编程中,如果一个包含状态的对象,在执行过程中操作不具备原子性,则会使此变量发生偏差。

  2、在并发编程中,如果一个包含状态的对象,在操作过程中存在多个竞态条件,结果会变不可靠。因为后执行的操作,可能会基于前一个操作的状态去执行某个操作,但前一个操作的结果可能会失效,导致后一个操作从全局看是错误的,这叫做先检查后执行错误。

  3、复合操作:先检查后执行;读取-修改-写入

  4、加锁机制

  5、内置锁:同步代码块包括两部分:一个作为锁的对象引用,另一个作为锁保护的代码块。Java内置锁相当于一个互斥锁。

  6、重入锁:指如果某个线程已经获取了某个锁,在流程处理过程中,又重新去获取这个锁,则将会成功。

  7、用锁来保护状态:由于锁能达到代码路径以串行执行,因此可以通过锁来构造一些协议,实现对共享状态的独占访问,遵循这些协议,则可达到状态一致性目的。避免产生竞态条件:原子操作,比如命中计数器的复合操作或者延迟初始化操作都需要是原子性的。如果在复合操作过程中持有一个锁,则复合操作会变成一个原子操作。但仅仅将复合操作封装到一个同步代码块中是不够的,需要在访问某个变量的所有位置上都使用同步,都使用同一个锁。

对于可能被多个线程同时访问的可变状态变量,在访问时需要同一个锁,这个变量就是被这个锁保护的。

每个对象虽然可以通过一个内置锁受到保护,但这种锁并不能阻止其他线程去访问这个对象,因为某个线程在获得这个对象的锁以后,并不能阻止的是其它线程去获得这个锁,想要对象中的共享状态变量安全,需要自行构造加锁协议或者同步策略,在程序中要自始至终的使用这个策略。

以上的意思是:如果某个对象中的复合操作或者延迟操作想要得到线程安全保护,那么只在这个对象的这些操作上进行内置锁保护是不够的,因为其他线程也会去访问这个对象的共享变量,如果访问的获取操作或者修改操作,那么这个共享变量就变得不安全,怎么达到共享安全呢,需要在这个共享变量的操作上全部使用锁或者不同的策略,这样不管执行什么操作,都是安全的。

还有,如果我们能达到在访问某个共享状态变量时候,都需要持有同一个锁才能访问这个共享状态变量,那么也能达到线程安全,这种安全是建立在这个锁保护的基础上。

  

JAVA并发编程之线程安全性的更多相关文章

  1. Java并发编程 (四) 线程安全性

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.线程安全性-原子性-atomic-1 1.线程安全性 定义: 当某个线程访问某个类时,不管运行时环境 ...

  2. Java并发编程 (五) 线程安全性

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.安全发布对象-发布与逸出 1.发布与逸出定义 发布对象 : 使一个对象能够被当前范围之外的代码所使用 ...

  3. Java并发编程:线程池的使用

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  4. Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition

    Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...

  5. Java并发编程:线程池的使用(转)

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  6. Java并发编程:线程控制

    在上一篇文章中(Java并发编程:线程的基本状态)我们介绍了线程状态的 5 种基本状态以及线程的声明周期.这篇文章将深入讲解Java如何对线程进行状态控制,比如:如何将一个线程从一个状态转到另一个状态 ...

  7. Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)

    Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) Java 并发编程 ...

  8. (转)Java并发编程:线程池的使用

    背景:线程池在面试时候经常遇到,反复出现的问题就是理解不深入,不能做到游刃有余.所以这篇博客是要深入总结线程池的使用. ThreadPoolExecutor的继承关系 线程池的原理 1.线程池状态(4 ...

  9. Java并发编程:线程池的使用(转载)

    转载自:https://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...

随机推荐

  1. maven 配置环境变量后报错jdk版本不符

    不需要再cmd 输入java -version,因为环境变量里配置的不一定是cmd显示版本,直接看环境变量改成maven要求的jdk版本即可.

  2. photoshop下载(ps)

    https://pan.baidu.com/s/1bNrUod2n1VqsA7Fr9RHtsg

  3. Jmeter进行分布式性能测试

    由于Jmeter本身的瓶颈,当需要模拟数以千计的并发用户时,使用单台机器模拟所有的并发用户就有些力不从心,甚至还会引起JAVA内存溢出的错误.要解决这个问题,可以使用分布式测试,运行多台机器运行所谓的 ...

  4. webpack搭建vue项目

    链接:https://blog.csdn.net/qq_42181069/article/details/81137180 __dirname : 文件的绝对路径

  5. pwn之exp问题反馈和ASLR认知

    如上问题是我执行脚本遇到的,改了脚本几次,依然没变,嗯...... 当我用了百度,据说是ALSR没关,的确,这导致我脚本中的addr是一个随机数,从而攻击失败 ##0x00:引用一下查到的知识:在传统 ...

  6. 重装VisualSVN Server报错

    由于eclipse无法连接SVN服务器,尝试着重装SVN,安装到一半时,弹出如下图所示错误: 打开提示窗口输入services.msc,进入服务界面: 发现VisualSVN Server服务无法启动 ...

  7. 一个简单insert 语句执行 40ms 原因剖析

    背景:一个简单的带有主键的insert 语句,居然要 40ms ,开发受不了,要求降低 因此我们要关注的的 数据从插入落地的IO 中间都干了什么 一.MySQL的文件 首先简单介绍一下MySQL的数据 ...

  8. mysql 表这段内容替换

    update `cr_article` set `img`=replace(`img`,'http://192.168.2.10/upload','http://zouke1220.oss-cn-be ...

  9. 设计模式课程 设计模式精讲 3-11 合成复用原则coding

    1 课堂概念 1.0 继承关系的选择 1.1 起名 1.2 定义 1.3 组合聚合优缺点 1.4 继承优缺点 1.5 组合聚合区别 2 代码演练 2.1 反例 2.2 正例 3 疑问解答3.1 疑问解 ...

  10. 番外篇!全球首个微信应用号开发教程!小程序 DEMO 视频奉上!

    大家好,我是博卡君.经过国庆节的七天假期,相信很多朋友都已经研究出自己的小程序 demo 了吧?我最近也利用休息时间关注了一下网上关于小程序开发的讨论,今天就利用这个番外篇谈谈自己对小程序的一些想法吧 ...