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. 【PAT甲级】1079 Total Sales of Supply Chain (25 分)

    题意: 输入一个正整数N(<=1e5),表示共有N个结点,接着输入两个浮点数分别表示商品的进货价和每经过一层会增加的价格百分比.接着输入N行每行包括一个非负整数X,如果X为0则表明该结点为叶子结 ...

  2. hackme.inndy.tw - pyyy

    0x01 反编译 1.第一次尝试的时候我直接在线反编译,部分结果如下. for (i, f) in enumerate(F): n = pow(f, m, g) this_is = 'Y-Combin ...

  3. HIS读书笔记

    医院的主要信息子系统,包括医院信息管理系统HIMS,放射科信息系统RIS,图像存档与传输系统PACS,检验信息系统LIS,医学信息传输标准与系统集成,以及临床路径和电子病历等. 医院信息系统一般划分为 ...

  4. 本地简单HTTP服务器

    cd进要启动服务器的目录 python -m http.server 7800 (Python 3.x) python -m SimpleHTTPServer 7998 (Pyhton2.x)

  5. Linux - 查看文件、文件夹、磁盘大小命令

    1. ls -lsh 2. du -sh du == disk usage (磁盘使用量,占用的磁盘空间) 一个文件占用的磁盘空间和一个文件的大小是两码事情.占用空间取决于文件系统的块(block)的 ...

  6. 【代码总结】SQL语句设计

    1.根据空值(NULL)检索条件 select * from user where age is not null; //查询年龄为null的所有用户 2.使用IN进行范围对比查询 ,5的所有用户 , ...

  7. spring boot加载配置文件的顺序

    四个默认加载配置文件地方的优先级,四个文件相同配置有优先级概念  不同位置相互补充 外部配置文件不建议使用,不符合maven项目结构,打包会打不进去

  8. 【JS 移动端】获取设置页面大小

    获取设置页面大小 function getMobileData() { var ismobile = false; browser = { versions: function () { var u ...

  9. vue 项目中的less

    收先要在cmd中运行 npm install less less-loader --save 然后会在 moudules文件夹中生成less 和less-loader <style lang=& ...

  10. apache、mysql、php核心、phpmyadmin的安装及相互关联

    1.apache的安装 https://blog.csdn.net/ashendove/article/details/52206198 里面的serverName  就是你在服务中 设置的apach ...