线程安全就是多线程訪问时,採用了加锁机制,当一个线程訪问该类的某个数据时,进行保护,其它线程不能进行訪问直到该线程读取完,其它线程才可使用。不会出现数据不一致或者数据污染。线程不安全就是不提供数据訪问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据

=================================================================
概念:
假设你的代码所在的进程中有多个线程在同一时候执行,而这些线程可能会同一时候执行这段代码。假设每次执行结果和单线程执行的结果是一样的,并且其它的变量的值也和预期的是一样的,就是线程安全的。
或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的运行结果存在二义性,也就是说我们不用考虑同步的问题。
线程安全问题都是由全局变量及静态变量引起的。
若每一个线程中对全局变量、静态变量仅仅有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同一时候运行写操作,一般都须要考虑线程同步,否则的话就可能影响线程安全。
安全性:
比方一个 ArrayList 类,在加入一个元素的时候,它可能会有两步来完毕:1. 在 Items[Size] 的位置存放此元素;2. 增大 Size 的值。
在单线程执行的情况下,假设 Size = 0,加入一个元素后,此元素在位置 0,并且 Size=1;
而如果是在多线程情况下,比方有两个线程,线程 A 先将元素存放在位置 0。可是此时 CPU 调度线程A暂停,线程 B 得到执行的机会。线程B也向此 ArrayList 加入元素,由于此时 Size 仍然等于 0 (注意哦,我们如果的是加入一个元素是要两个步骤哦,而线程A只完毕了步骤1),所以线程B也将元素存放在位置0。然后线程A和线程B都继续执行,都添加 Size 的值。
那好,我们来看看 ArrayList 的情况,元素实际上仅仅有一个,存放在位置 0,而 Size 却等于 2。这就是“线程不安全”了。
安全性:
线程安全性不是一个非真即假的命题。 Vector 的方法都是同步的,而且 Vector 明白地设计为在多线程环境中工作。可是它的线程安全性是有限制的,即在某些方法之间有状态依赖(类似地,假设在迭代过程中 Vector 被其它线程改动,那么由 Vector.iterator() 返回的 iterator会抛出ConcurrentModifiicationException)。
对于 Java 类中常见的线程安全性级别,没有一种分类系统可被广泛接受,只是重要的是在编写类时尽量记录下它们的线程安全行为。
Bloch 给出了描写叙述五类线程安全性的分类方法:不可变、线程安全、有条件线程安全、线程兼容和线程对立。仅仅要明白地记录下线程安全特性,那么您是否使用这样的系统都没关系。这样的系统有其局限性 -- 各类之间的界线不是百分之百地明白,并且有些情况它没照应到 -- 可是这套系统是一个非常好的起点。这样的分类系统的核心是调用者能否够或者必须用外部同步包围操作(或者一系列操作)。以下几节分别描写叙述了线程安全性的这五种类别。

不可变

不可变的对象一定是线程安全的,而且永远也不须要额外的同步[1]。由于一个不可变的对象仅仅要构建正确,其外部可见状态永远也不会改变,永远也不会看到它处于不一致的状态。Java 类库中大多数基本数值类如 Integer 、 String 和 BigInteger 都是不可变的。
须要注意的是,对于Integer,该类不提供add方法,加法是使用+来直接操作。而+操作是不具线程安全的。这是提供原子操作类AtomicInteger的原。
线程安全
线程安全的对象具有在上面“线程安全”一节中描写叙述的属性 -- 由类的规格说明所规定的约束在对象被多个线程訪问时仍然有效,无论执行时环境怎样排线程都不须要不论什么额外的同步。这样的线程安全性保证是非常严格的 -- 很多类,如 Hashtable 或者 Vector 都不能满足这样的严格的定义。

有条件的

有条件的线程安全类对于单独的操作能够是线程安全的,可是某些操作序列可能须要外部同步。条件线程安全的最常见的样例是遍历由 Hashtable 或者 Vector 或者返回的迭代器 -- 由这些类返回的 fail-fast 迭代器假定在迭代器进行遍历的时候底层集合不会有变化。为了保证其它线程不会在遍历的时候改变集合,进行迭代的线程应该确保它是独占性地訪问集合以实现遍历的完整性。通常,独占性的訪问是由对锁的同步保证的 -- 而且类的文档应该说明是哪个锁(一般是对象的内部监视器(intrinsic monitor))。
如果对一个有条件线程安全类进行记录,那么您应该不仅要记录它是有条件线程安全的,并且还要记录必须防止哪些操作序列的并发訪问。用户能够合理地如果其它操作序列不须要不论什么额外的同步。
线程兼容
线程兼容类不是线程安全的,可是能够通过正确使用同步而在并发环境中安全地使用。这可能意味着用一个 synchronized 块包围每个方法调用,或者创建一个包装器对象,当中每个方法都是同步的(就像 Collections.synchronizedList() 一样)。也可能意味着用 synchronized 块包围某些操作序列。为了最大程度地利用线程兼容类,假设全部调用都使用同一个块,那么就不应该要求调用者对该块同步。这样做会使线程兼容的对象作为变量实例包括在其它线程安全的对象中,从而能够利用其全部者对象的同步。
很多常见的类是线程兼容的,如集合类 ArrayList 和 HashMap 、 java.text.SimpleDateFormat 、或者 JDBC 类 Connection 和 ResultSet 。

线程对立

线程对立类是那些无论是否调用了外部同步都不能在并发使用时安全地呈现的类。线程对立非常少见,当类改动静态数据,而静态数据会影响在其它线程中运行的其它类的行为,这时一般会出现线程对立。线程对立类的一个样例是调用 System.setOut() 的类。

转载于:https://www.cnblogs.com/zfyouxi/p/4009325.html

线程安全和线程不安全理解相关推荐

  1. iOS开发 - 线程与进程的认识与理解

    进程: 进程是指在系统中正在运行的一个应用程序,比如同时打开微信和Xcode,系统会分别启动2个进程; 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内; 线程: 一个进程要想执行任务 ...

  2. c++ 获取线程id_5分钟带你完全理解什么是线程

    一.线程概念 介绍概念之前,先画个图吧,依旧是全博客园最丑图,不接受反驳! 简单说明一下:进程在其内部创建线程,线程有自己的PCB,但没有独立的地址空间. 线程和进程具有以下特征和区别: LWP:li ...

  3. python是如何实现进程池和线程池的_进程、线程、线程池和协程如何理解?

    1.进程.线程.线程池的概念 进程是一个动态的过程,是一个活动的实体.简单来说,一个应用程序的运行就可以被看做是一个进程,而线程,是运行中的实际的任务执行者.可以说,进程中包含了多个可以同时运行的线程 ...

  4. Java线程与Android线程,Android线程篇(三):深入理解Java线程池(一)

    上篇文章我们讲解了Java的四种线程池,我们知道如何去使用四种线程池,以及在合适的情况下使用合适的线程池,常言道,不懂原理的厨师不是好的程序员,所以本篇文章,就带大家一起去探寻Java线程池的秘密. ...

  5. Java线程等待唤醒机制(加深理解)

    今天看源码的时候遇到这样一个场景,某线程里面的逻辑需要等待异步处理结果返回后才能继续执行.或者说想要把一个异步的操作封装成一个同步的过程.这里就用到了线程等待唤醒机制,下面具体看一下. 等待唤醒机制示 ...

  6. 理解套间(涉及进程、线程、COM线程模型)(转载)

    简序 大学毕业前的最后一学期,在一家公司实习,当时的工作需要用到一些操作系统提供的组件.那时候只知道COM这个名词,并不知道到底是怎么回事,只知道上网到处找别人的源码解决自己的问题:那段日子到现在回忆 ...

  7. Java线程池几个参数的理解

    线程池几个参数的理解: 比如去火车站买票, 有10个售票窗口, 但只有5个窗口对外开放. 那么对外开放的5个窗口称为核心线程数, 而最大线程数是10个窗口.如果5个窗口都被占用, 那么后来的人就必须在 ...

  8. Thread线程从零认识到深层理解——初识

    线程系列目录 Thread线程从零认识到深层理解--初识 Thread线程从零认识到深层理解--六大状态 Thread线程从零认识到深层理解--wait()与notify() Thread线程从零认识 ...

  9. 【并行计算-CUDA开发】CUDA线程、线程块、线程束、流多处理器、流处理器、网格概念的深入理解

    GPU的硬件结构,也不是具体的硬件结构,就是与CUDA相关的几个概念:thread,block,grid,warp,sp,sm. sp: 最基本的处理单元,streaming processor  最 ...

  10. CPU核心数线程数、程序进程线程、并发并行的简单理解

    CPU核心数线程数.程序进程线程.并发并行.简单理解和区分 这篇文章是对上述感念的简单理解,想深入研究可以看看<计算机组成原理> CPU的核心数 线程数 当我们买电脑的时候,会看到CPU的 ...

最新文章

  1. Nginx反向代理负载均衡
  2. php动态数组的存储过程,PHP数组作为存储过程的输入
  3. Exchange2010配置实验(六)部署forefront到edge服务器
  4. lhgdialog 4.2.0 正式版发布
  5. java最好的开发工具_IntelliJ IDEA Ultimate Edition 2018 最好的 Java 开发工具
  6. 《C++ Primer中文版(第5版)》学习笔记与习题完整发布!
  7. Intellij IDEA 使用jrebel运行spring-boot并实现自动编译进行热部署
  8. wincc版本升级_【西门子】WinCC V7.4 SP1:常规信息和安装 (较新).pdf
  9. Adapter模式简述
  10. mugen linux主程序,Mugen主程序报错汇总
  11. ICCV 2021 | FACIAL :动态谈话人脸视频生成,姿态,眨眼皆可控!
  12. 这几天阿里云发生故障事件,身为程序员慌得一批……
  13. 免费的查询IP归属地接口分享
  14. 详解php与mysql的关系
  15. 这一刻,听见华为FTTR的星光四重奏
  16. 10种室内定位技术原理深度解析
  17. 利用TI的官网Sysconfig配置beagleboard-x15 linux系统中的串口
  18. Android层面上对sensor及event事件的处理
  19. 提升项目经理谈话能力的十个实用技巧
  20. 合肥工业大学宣城校区2018年-2019年第一学期(大三上学期)物联网工程专业资料汇总(含课件、个人实验报告、实验代码、课设报告等)

热门文章

  1. 历史上的甲子年灾难有哪些?
  2. 赚钱也好,投资也好,本质上都是一种专业技能
  3. 我们想赚钱,首先要帮助我们的团队,让他们提升能力让他们赚到钱
  4. 手把手教你如何罗列提纲,避开这3个坑,提升写作效率50%
  5. win10家庭版与专业版有什么区别?
  6. 为什么手机用久了,就不那么流畅了,啥原因?
  7. 线上售楼处,卖房神器还是营销噱头?
  8. php截取一个中文字符,php中的一个中文字符串截取函数
  9. powerbi发布本地_PowerBI中本地数据的注意事项
  10. ubuntu 安装sql_在Ubuntu上进行SQL Server安装和故障排除