线程安全

并发容器的原理,七大并发容器详解、及使用场景

夙愿已清 提交于 2019-12-11 22:40:49
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 并发容器的由来 在Java并发编程中,经常听到Java集合类,同步容器、并发容器,那么他们有哪些具体分类,以及各自之间的区别和优劣呢? 只有把这些梳理清楚了,你才能真正掌握在高并发的环境下,正确使用好并发容器,我们先从Java集合类,同步容器谈起。 1.什么是同步容器 Java的集合容器框架中,主要有四大类别:List、Set、Queue、Map,大家熟知的这些集合类ArrayList、LinkedList、HashMap这些容器都是非线程安全的。 如果有多个线程并发地访问这些容器时,就会出现问题。因此,在编写程序时,在多线程环境下必须要求程序员手动地在任何访问到这些容器的地方进行同步处理,这样导致在使用这些容器的时候非常地不方便。 所以,Java先提供了同步容器供用户使用。 同步容器可以简单地理解为通过synchronized来实现同步的容器 ,比如Vector、Hashtable以及SynchronizedList等容器。 2.同步容器,主要的分类: Vector Stack HashTable Collections.synchronized方法生成 同步容器面临的问题 可以通过查看Vector,Hashtable等这些同步容器的实现代码,可以看到这些容器实现线程安全的方式就是将它们的状态封装起来,

reentrant,thread-safe 和 async-signal-safe

烈酒焚心 提交于 2019-12-11 20:58:58
可重入,线程安全和异步信号安全POSIX定义: Reentrant Function A function whose effect, when called by two or more threads, is guaranteed to be as if the threads each executed the function one after another in an undefined order, even if the actual execution is interleaved. Thread-Safe A function that may be safely invoked concurrently by multiple threads. Each function defined in the System Interfaces volume of IEEE Std 1003.1-2001 is thread-safe unless explicitly stated otherwise. Async-Signal-Safe Function A function that may be invoked, without restriction, from signal-catching functions. No function is async

【多线程】如何保证线程安全

若如初见. 提交于 2019-12-11 13:29:04
一、线程安全等级 之前的博客 中已有所提及“线程安全”问题,一般我们常说某某类是线程安全的,某某是非线程安全的。其实线程安全并不是一个“非黑即白”单项选择题。按照“线程安全”的安全程度 由强到弱 来排序,我们可以将java语言中各种操作共享的数据分为以下5类: 不可变、绝对线程安全、相对线程安全、线程兼容和线程对立 。 1、不可变 在java语言中,不可变的对象一定是线程安全的,无论是对象的方法实现还是方法的调用者,都不需要再采取任何的线程安全保障措施。如final关键字修饰的数据不可修改,可靠性最高。 2、绝对线程安全 绝对的线程安全完全满足Brian GoetZ给出的线程安全的定义,这个定义其实是很严格的,一个类要达到“不管运行时环境如何,调用者都不需要任何额外的同步措施”通常需要付出很大的代价。 3、相对线程安全 相对线程安全就是我们通常意义上所讲的一个类是“线程安全”的。 它需要保证对这个对象单独的操作是线程安全的,我们在调用的时候不需要做额外的保障措施,但是对于一些特定顺序的连续调用,就可能需要在调用端使用额外的同步手段来保证调用的正确性。 在java语言中,大部分的线程安全类都属于相对线程安全的,例如Vector、HashTable、Collections的synchronizedCollection()方法保证的集合。 4、线程兼容

《C#设计模式》【单例模式】

泄露秘密 提交于 2019-12-11 12:27:41
《C#设计模式》- 单例模式 深度解析六种单例模式实现方法,以及安全,性能分析 第一种: 不是线程安全的 public sealed class Singleton { private static Singleton instance = null ; private Singleton() { } public static Singleton Instance { get { if (instance == null) { instance = new Singleton(); } return instance; } } } 上述内容不是线程安全的。两个不同的线程都可以评估测试 if (instance==null) 并发现它为 true ,然后两个都创建实例,这违反了单例模式。请注意,实际上,在计算表达式之前可能已经创建了实例,但是内存模型不保证其他线程可以看到实例的新值,除非已经传递了合适的内存屏障(互斥锁) 第二种 : 简单线程安全 public sealed class Singleton { private static Singleton instance = null; private static readonly object padlock = new object(); Singleton() { } public static Singleton

线程安全和线程不安全理解

旧时模样 提交于 2019-12-11 12:02:34
线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。 线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据 概念: 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和 单线程 运行的结果是一样的,而且其他的 变量 的值也和预期的是一样的,就是线程安全的。 或者说:一个类或者程序所提供的接口对于线程来说是 原子操作 或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。 线程安全问题都是由 全局变量 及 静态变量 引起的。 若每个线程中对 全局变量 、 静态变量 只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑 线程同步 ,否则的话就可能影响线程安全。 安全性: 比如一个 ArrayList 类,在添加一个元素的时候,它可能会有两步来完成:1. 在 Items[Size] 的位置存放此元素;2. 增大 Size 的值。 在 单线程 运行的情况下,如果 Size = 0,添加一个元素后,此元素在位置 0,而且 Size=1; 而如果是在 多线程 情况下,比如有两个线程,线程 A 先将元素存放在位置

46 容器(五)——Vector,线程安全版的ArrayList

邮差的信 提交于 2019-12-11 10:20:30
在List中,最常用的三个List为: ArrayList 频繁查询时推荐使用 LinkedList 频繁增删时推荐使用 Vector 线程安全时推荐使用 Vector的底层跟ArrayList相差无几,在需要线程安全的方法中使用了synchronized。 来源: https://www.cnblogs.com/Scorpicat/p/12020653.html

单例模式

ぐ巨炮叔叔 提交于 2019-12-10 22:45:43
定义: 单例模式 (Singleton Pattern)属于创建型模式,提供了一种创建对象的最佳方式。 单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点 实现方式 :“饿汉式” and “懒汉式”    “饿汉式” :在类加载的时候就实例化对象,通俗来说就是:不管这个对象你要不要用,我都先实例化出来,要用的时候直接取就行 “懒汉式” :也就是我们常说的 延迟加载 。通俗来说就是:只要你要用这个对象,我才去实例化这个对象,然后在取来用 通过定义我们就知道这两种方式的差异了,“饿汉式”在不采取同步的方式的时候就是线程安全的,而“懒汉汉”则需要采取同步的措施来保证线程安全,当然也可以不采取同步的措施,例如采用枚举类来实现单例模式,这个接下来细说。 优点:    1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。 2、避免对资源的多重占用(比如写文件操作)。 缺点: 没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。 具体实现 : 也就是上代码啦!!! 1、“饿汉式” 1 // 饿汉式 demo1 2 public class Singleton1 { 3 4 // 必须私有化构造函数 5 private Singleton1(){} 6 7 // 先初始化对象 8 private static

别翻了,这篇文章就是要让你搞定Java多线程!

孤人 提交于 2019-12-10 22:39:48
1. 理解线程与进程 由于并发肯定涉及到多线程,因此在进入并发编程主题之前,我们先来了解一下进程和线程的由来,这对后面对并发编程的理解将会有很大的帮助。 进程和线程的对比这一知识点由于过于基础,正因为过于基础,所以我们更应该透彻它!我们必须掌握什么是线程和进程,掌握线程与进程的关系、区别及优缺点 ! 1.1、何为进程? 首先我们来看一下进程的概念: 进程 :是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。 看完之后,是不是感觉很抽象?很懵bi?懵bi就对了,说明你和我智商一样高....~开个玩笑~ 不妨先憋弃上面的概念,放松一下大脑,双击打开LOL,秒选德马打野,输了直接退出游戏并且保持微笑,然后正襟危坐心平气和的看宜春写的博客.... 这个时候的你不仅仅是愉快的撸了一把游戏,而且还亲自体验撸了一把进程...其实在你双击打开LOL的时候就已经创建了进程,此话怎讲?众所周知,我们的电脑安装的软件比如:LOL、微信、谷歌等等都是存储在我们的硬盘上的,硬盘上的数据可以说是永久存储(ORM),当我们双击LOL的时候,LOL程序执行就进入了内存中,所有的程序必须进入内存中才能执行,内存属于临时存储(RAM),而

线程安全

╄→гoц情女王★ 提交于 2019-12-10 14:22:13
在这三篇文章中,我将详细介绍原理操作,内存障碍和线程之间数据的快速交换,以及“sequence-points”示例中的“execute-around-idiom”。同时,我们将尝试一起做一些有用的事情。 标准C ++库中没有线程安全的容器(数组,列表,映射…),可以在多个线程中使用它们而无需附加锁。在使用标准容器进行多线程交换的情况下,可能会忘记使用互斥锁保护其中一个代码段,或者错误地使用另一个互斥锁来保护它。 显然,如果开发人员使用自己的解决方案而不是标准的解决方案,则会犯更多的错误。而且,如果任务很复杂,以至于没有任何标准解决方案,那么开发人员在尝试寻找解决方案时将充满错误。 依靠“实践大于理论”的原则,我们将努力创造出一个解决这个问题的最佳方法,而不是纸上谈兵。 在本文中,我们将实现使所有对象成为线程安全对象的智能指针,其性能与优化的无锁容器相同。 使用此类指针的简化,非优化示例: int main() {   contfree_safe_ptr< std::map< std::string, int > > safe_map_string_int;   std::thread t1( & { safe_map_string_int->emplace(“apple”, 1); });   std::thread t2( & { safe_map_string_int-

静态变量、实例变量、局部变量与线程安全

天大地大妈咪最大 提交于 2019-12-10 04:50:56
静态变量:线程非安全。 加static关键字的变量,只能放在类里, 不能放到方法里 。 静态变量有默认初始化值。 静态变量表示所有实例共享的一个属性,位于方法区,共享一份内存,而成员变量是对象的特殊描述,不同对象的实例变量被分配在不同的内存空间, 一旦静态变量被修改,其他对象均对修改可见,故线程非安全。 实例变量:单例模式(只有一个对象实例存在)线程非安全,非单例线程安全。 成员变量(实例变量): 1、成员变量定义在类中,即类中的普通变量,在整个类中都可以被类中方法所访问(如过和局部变量重名,需用this关键字)。 2、成员变量随着对象的建立而建立,随着对象的消失而消失, 存在于对象所在的堆内存中 。 3、 成员变量有默认初始化值 实例变量为对象实例私有,在虚拟机的堆中分配,若在系统中只存在一个此对象的实例,在多线程环境下,被某个线程修改后,其他线程对修改均可见,故线程非安全;如果每个线程执行都是在不同的对象中,那对象与对象之间的实例变 量的修改将互不影响,故线程安全。 成员变量和类变量的区别: 1、两个变量的生命周期不同 成员变量随着对象的创建而存在,随着对象的回收而释放。 静态变量随着类的加载而存在,随着类的消失而消失,且优先于对象存在。 2、调用方式不同 成员变量只能被对象调用。 静态变量可以被对象调用,还可以被类名调用。 3、数据存储位置不同 成员变量存储在堆内存的对象中