您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > JAVA

线程安全问题无大小:Java中的线程安全之操作共享数据分类

时间:2021-05-18 09:19:01  来源:  作者:程序员的苦咖啡

线程安全这个名称,相信稍有经验的程序员都会听说过,甚至在代码编写和走查的时候可能还会经常挂在嘴边,并且在面试中是问的最多的,但凡有处理线程安全问题经验丰富的程序员,都会很吃香。线程安全怎么来定义呢?一本书中曾做过定义:“当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象是线程安全的”。

今天就来说一说JAVA语言中的线程安全,线程安全问题,无非就是对共享数据的处理,在Java语言中,处理共享数据可以分为:不可变、绝对线程安全、相对线程安全、线程兼容和线程对立。

一、不可变

在Java语言中,不可变 (Immutable)的对象一定是线程安全的,无论是对象的方法实现还是方法的调用者,都不需要再采取任何的线程安全保障措施,只要一个不可变的对象被正确地构建出来,那 其外部的可见状态永远也不会改变,永远也不会看到它在多个线程之中处于不一致的状态。“不可变”带来的安全性是最简单和最纯粹的。如果共享数据是一个基本数据类型,那么只要在定义时使用final关键字修 饰它就可以保证它是不可变的。如果共享数据是一个对象,那就需要保证对象的行为不会对 其状态产生任何影响才行,大家都熟悉java.lang.String类的对象,它是一个典型的不可变对象,我们调用它的substring()、replace()和concat()这些方法都不会影响它原来的值,只会返回一个新构造的字符串对象。

线程安全问题无大小:Java中的线程安全之操作共享数据分类

 

保证对象行为不影响自己状态的途径有很多种,其中最简单的就是把对象中带有状态的变量都声明为final,这样在构造函数结束之后,它就是不可变的,比如java.lang.Integer的构造函数,它通过将内部状态变量value定义为final来保障状态不变。

线程安全问题无大小:Java中的线程安全之操作共享数据分类

 

二、绝对线程安全

绝对的线程安全就是要完全满足:一个类要达到“不管运行时环境如何,调用者都不需要任何额外的同步措施”通常需要付出很大的,甚至有时候是不切实际的代价。在Java API中标注自己是线程安全的类,大多数都不是绝对的线程安全。java.util.Vector是一个线程安全的容器,因为它的add()、get()和size()这类方法都是被synchronized修饰的,尽管这样效率很低,但确实是安全的。但是,即使它所有的方法都被修饰成同步,也不意味着调用它的时候永远都不再需要同步手段了。

线程安全问题无大小:Java中的线程安全之操作共享数据分类

 

假如我们在另外一个A方法中调用Vector类中的线程安全的方法,如果 A方法不加synchronized关键字,这个A方法也是线程非安全的。

三、相对线程安全

相对的线程安全就是我们通常意义上所讲的线程安全,它需要保证对这个对象单独的操作是线程安全的,我们在调用的时候不需要做额外的保障措施,但是对于一些特定顺序的连 续调用,就可能需要在调用端使用额外的同步手段来保证调用的正确性。在Java语言中,大部分的线程安全类都属于这种类型,例如Vector、HashTable、Collections的synchronizedCollection()方法包装的集合等。

四、线程兼容

线程兼容是指对象本身并不是线程安全的,但是可以通过在调用端正确地使用同步手段来保证对象在并发环境中可以安全地使用,我们平常说一个类不是线程安全的,绝大多数时候指的是这一种情况。Java API中大部分的类都是属于线程兼容的,如与前面的Vector和HashTable相对应的集合类ArrayList和HashMap等。

五、线程对立

线程对立是指无论调用端是否采取了同步措施,都无法在多线程环境中并发使用的代码。由于Java语言天生就具备多线程特性,线程对立这种排斥多线程的代码是很少出现的,而且通常都是有害的,应当尽量避免。一个线程对立的例子是Thread类的suspend()和resume()方法,如果有两个线程同时持有一个线程对象,一个尝试去中断线程,另一个尝试去恢复线程,如果并发进行的话,无论调用时是否进行了同步,目标线程都是存在死锁风险的,如果suspend()中断的线程就是即将要执行resume()的那个线程,那就肯定要产生死锁了。也正是由于这个原因,suspend()和resume()方法已经被JDK声明废(@Deprecated)了。常见的线程对立的操作还有System.setIn()、Sytem.setOut()和
System.runFinalizersOnExit()等。

线程安全问题无大小:Java中的线程安全之操作共享数据分类

 

面向过程的编程思想极大地提升了现代软件开发的生产效率和软件可以达到的规模,但是现实世界与计算机世界之间不可避免地存在一些差异。有时候,良好的设计原则不得不向现实做出一些让步,我们必须让程序在计算机中正确无误地运行,然后再考虑如何将代码组织得更好,让程序运行得更快。专业一点讲,就是高效并发,高效并发首先需要保证并发的正确性,然后在此基础上实现高效。所以对于线程并发安全问题的一些基础知识,我们需要扎实的进行了解。



Tags:线程安全   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
线程安全这个名称,相信稍有经验的程序员都会听说过,甚至在代码编写和走查的时候可能还会经常挂在嘴边,并且在面试中是问的最多的,但凡有处理线程安全问题经验丰富的程序员,都会很...【详细内容】
2021-05-18  Tags: 线程安全  点击:(202)  评论:(0)  加入收藏
什么是进程?电脑中时会有很多单独运行的程序,每个程序有一个独立的进程,而进程之间是相互独立存在的。比如下图中的QQ、酷狗播放器、电脑管家等等。 什么是线程?进程想要执行任...【详细内容】
2020-03-15  Tags: 线程安全  点击:(98)  评论:(0)  加入收藏
在我们日常写程序的过程中,免不了与文件系统打交道,各种开发语言都提供了与文件系统交互的指令函数,比如Python中的os模块,就提供了许多这样的指令函数,今天就以创建文件夹为例,来...【详细内容】
2019-12-23  Tags: 线程安全  点击:(101)  评论:(0)  加入收藏
0. HashMap 简单说几句我们在学习 HashMap 的时候,都知道 HashMap 是非线程安全的,同时我们知道 HashTable 是线程安全的,因为里面的方法使用了 synchronized 进行同步。但是...【详细内容】
2019-09-03  Tags: 线程安全  点击:(217)  评论:(0)  加入收藏
作者 l Hollis 来源 l Hollis(ID:hollischuang)JVM内存结构,是很重要的知识,相信每一个静心准备过面试的程序员都可以清楚的把堆、栈、方法区等介绍的比较清楚。 上图,是一张在作...【详细内容】
2019-07-30  Tags: 线程安全  点击:(299)  评论:(0)  加入收藏
▌简易百科推荐
一、Redis使用过程中一些小的注意点1、不要把Redis当成数据库来使用二、Arrays.asList常见失误需求:把数组转成list集合去处理。方法:Arrays.asList 或者 Java8的stream流式处...【详细内容】
2021-12-27  CF07    Tags:Java   点击:(3)  评论:(0)  加入收藏
文章目录 如何理解面向对象编程? JDK 和 JRE 有什么区别? 如何理解Java中封装,继承、多态特性? 如何理解Java中的字节码对象? 你是如何理解Java中的泛型的? 说说泛型应用...【详细内容】
2021-12-24  Java架构师之路    Tags:JAVA   点击:(5)  评论:(0)  加入收藏
大家好!我是老码农,一个喜欢技术、爱分享的同学,从今天开始和大家持续分享JVM调优方面的经验。JVM调优是个大话题,涉及的知识点很庞大 Java内存模型 垃圾回收机制 各种工具使用 ...【详细内容】
2021-12-23  小码匠和老码农    Tags:JVM调优   点击:(11)  评论:(0)  加入收藏
前言JDBC访问Postgresql的jsonb类型字段当然可以使用Postgresql jdbc驱动中提供的PGobject,但是这样在需要兼容多种数据库的系统开发中显得不那么通用,需要特殊处理。本文介绍...【详细内容】
2021-12-23  dingle    Tags:JDBC   点击:(12)  评论:(0)  加入收藏
Java与Lua相互调用案例比较少,因此项目使用需要做详细的性能测试,本内容只做粗略测试。目前已完成初版Lua-Java调用框架开发,后期有时间准备把框架进行抽象,并开源出来,感兴趣的...【详细内容】
2021-12-23  JAVA小白    Tags:Java   点击:(10)  评论:(0)  加入收藏
Java从版本5开始,在 java.util.concurrent.locks包内给我们提供了除了synchronized关键字以外的几个新的锁功能的实现,ReentrantLock就是其中的一个。但是这并不意味着我们可...【详细内容】
2021-12-17  小西学JAVA    Tags:JAVA并发   点击:(10)  评论:(0)  加入收藏
一、概述final是Java关键字中最常见之一,表示“最终的,不可更改”之意,在Java中也正是这个意思。有final修饰的内容,就会变得与众不同,它们会变成终极存在,其内容成为固定的存在。...【详细内容】
2021-12-15  唯一浩哥    Tags:Java基础   点击:(14)  评论:(0)  加入收藏
1、问题描述关于java中的日志管理logback,去年写过关于logback介绍的文章,这次项目中又优化了下,记录下,希望能帮到需要的朋友。2、解决方案这次其实是碰到了一个问题,一般的情况...【详细内容】
2021-12-15  软件老王    Tags:logback   点击:(17)  评论:(0)  加入收藏
本篇文章我们以AtomicInteger为例子,主要讲解下CAS(Compare And Swap)功能是如何在AtomicInteger中使用的,以及提供CAS功能的Unsafe对象。我们先从一个例子开始吧。假设现在我们...【详细内容】
2021-12-14  小西学JAVA    Tags:JAVA   点击:(21)  评论:(0)  加入收藏
一、概述观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监听者,类似监听器的存在,一旦被观察/监听的目标发生的情况,就会被监听者发现,这么想来目标发生情况到观察...【详细内容】
2021-12-13  唯一浩哥    Tags:Java   点击:(16)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条