线程安全

HashMap和Hashtable区别

此生再无相见时 提交于 2019-11-29 00:04:00
HashMap和Hashtable的比较是Java面试中的常见问题,用来考验程序员是否能够正确使用集合类以及是否可以随机应变使用多种思路解决问题。HashMap的工作原理、ArrayList与Vector的比较以及这个问题是有关Java 集合框架的最经典的问题。Hashtable是个过时的集合类,存在于Java API中很久了。在Java 4中被重写了,实现了Map接口,所以自此以后也成了Java集合框架中的一部分。Hashtable和HashMap在Java面试中相当容易被问到,甚至成为了集合框架面试题中最常被考的问题,所以在参加任何Java面试之前,都不要忘了准备这一题。 这篇文章中,我们不仅将会看到HashMap和Hashtable的区别,还将看到它们之间的相似之处。 HashMap和Hashtable的区别 HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别。主要的区别有:线程安全性,同步(synchronization),以及速度。 HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。 HashMap是非synchronized

单例模式的几种实现方式及对比

柔情痞子 提交于 2019-11-29 00:01:43
所谓单例就是在系统中只有一个该类的实例。 单例模式的核心分以下三个步骤: 构造方法私有化。即不能在类外实例化,只能在类内实例化。 在本类中创建本类的实例。 在本类中提供给外部获取实例的方式。 单例模式的实现方式有两种:饿汉模式和懒汉模式。 饿汉模式 不管现在需不需要,先创建实例。关键在于“饿”,饿了就要立即吃。 静态常量 这里将类的构造器私有化,就不能在外部通过new关键字创建该类的实例,然后定义了一个该类的常量,用static修饰,以便外部能够获得该类实例(通过HungryStaticConstantSingleton. INSTANCE 获得)。也可以不加final关键字,具体看自己的需求。 1 /** 2 * 恶汉模式-静态常量,简洁直观 3 */ 4 public class HungryStaticConstantSingleton{ 5 //构造器私有化 6 private HungryStaticConstantSingleton() { 7 } 8 //静态变量保存实例变量 并提供给外部实例 9 public final static HungryStaticConstantSingleton INSTANCE = new HungryStaticConstantSingleton(); 10 } 枚举 这种方式是最简洁的,不需要考虑构造方法私有化

什么是线程安全和线程不安全

余生长醉 提交于 2019-11-28 23:59:48
首先要明白线程的工作原理,jvm有一个main memory,而每个线程有自己的working memory,一个线程对一个variable进行操作时,都要在自己的working memory里面建立一个copy,操作完之后再写入main memory。多个线程同时操作同一个variable,就可能会出现不可预知的结果。根据上面的解释,很容易想出相应的scenario。 而用synchronized的关键是建立一个monitor,这个monitor可以是要修改的variable也可以其他你认为合适的object比如method,然后通过给这个monitor加锁来实现线程安全,每个线程在获得这个锁之后,要执行完 load到workingmemory -> use&assign -> store到mainmemory 的过程,才会释放它得到的锁。这样就实现了所谓的线程安全。 ------------------------------------------------------ 什么是线程安全?线程安全是怎么完成的(原理)? 线程安全就是说多线程访问同一代码,不会产生不确定的结果。编写线程安全的代码是低依靠线程同步。 ------------------------------------------------------ 在接口方式中,线程有一个共享的数据成员,即:

Java 并发 – 线程安全?

孤街浪徒 提交于 2019-11-28 23:59:26
线程安全的定义常常让人迷惑,搜索引擎会发现无数定义,比如: 多个线程同时执行也能正确工作就是线程安全的代码 多个线程同时执行能以正确的方式操纵共享数据就是线程安全的代码。 而且还有很多类似的定义 你是否认为这种定义实际上没有任何意义而且还让人更加迷惑?虽然这些定义没错,但事实是他们没有提供任何实际的帮助或观点。我们如何区分线程安全类和不安全类?我们所谓的“安全”是什么意思? 线程安全的正确性是什么? 线程安全的任何合理定义的核心是正确性的概念。因此,在了解线程安全之前,我们首先应该理解这个“正确”。 正确性意味着一个类符合它的规范。 一个好的类规范将在任何给定的时间拥有关于一个类的状态的所有信息,在其上执行某些操作以及它的后置条件。但我们经常没有为我们的类写出足够的规范,我们怎么可能知道它们能正确的使用呢?我们不能,但这并不能阻止我们使用它们,一旦我们说服自己“代码有效”。这种“代码自信”来自于我们接近正确。 乐观地将“正确性”定义为可以被识别的东西,现在我们可以用一种不那么绕的方式定义线程安全: 当一个类在从多个线程访问时继续正常运行时,它是线程安全的 。 不管运行时环境线程调度如何交织,只有当从多个线程访问它行为正确,以及调用代码的部分没有额外的同步或其他协调,那么这个类是线程安全的 如果这个宽泛的“正确性”让你觉得比较烦

SQLite 线程安全和并发

老子叫甜甜 提交于 2019-11-28 23:59:11
SQLite 与线程 SQLite 是线程安全的。 线程模型 SQLite 支持如下三种线程模型 单线程模型 这种模型下,所有互斥锁都被禁用,同一时间只能由一个线程访问。 多线程模型 这种模型下,一个连接在同一时间内只有一个线程使用就是安全的。 串行模型 开启所有锁,可以随意访问。 设置线程模型 SQLite 可以通过以下三种方式进行线程模型的设置,在实际应用中选择任一一项都可以。 编译期设定 通过 SQLITE_THREADSAFE 这个参数进行编译器的设定来选择线程模型 初始化设定 通过调用 sqlite3_config() 可以在 SQLite 初始化时进行设定 运行时设定 通过调用 sqlite3_open_v2() 接口指定数据库连接的数据库模型 SQLite 并发和事务 事务 事务是 SQLite 的核心概念。对数据库的操作 (绝大部分) 会被打包成一个事务进行提交,需要注意的是,这里的打包成事务是自动开启的。举例而言,如果简单在一个 for 循环语句里向数据库中插入 10 条数据,意味着将自动生成 10 个事务。但需要注意的是事务是非常耗时的,一般而言, SQLite 每秒能够轻松支持 50000 条的数据插入,但是每秒仅能够支持几十个事务。一般而言,事务速度受限于磁盘速度。所以在批量插入时需要考虑禁用自动提交,将其用 BEGIN ... COMMIT 打包成一个事务

线程安全性问题

淺唱寂寞╮ 提交于 2019-11-28 23:15:06
什么是线程安全性 当多个线程访问某个类,不管运行时环境采用何种调度方式或者这些线程如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类为线程安全的。----《并发编程实战》。 什么是线程不安全 多线程并发访问时,得不到正确的结果。 结果: 产生线程不安全问题的原因: num++ 不是原子性操作,被拆分成好几个步骤,在多线程并发执行的情况下,因为cpu调度,多线程快递切换,有可能两个同一时刻都读取了同一个num值,之后对它进行+1操作,导致线程安全性。 原子性操作 什么是原子性操作 一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。通俗点讲:操作要成功一起成功、要失败大家一起失败。 如何把非原子性操作变成原子性 synchronize关键字,使得操作具有原子性 volatile关键字仅仅保证可见性,并不保证原子性 深入理解synchronized 内置锁:每个java对象都可以用做一个实现同步的锁,这些锁称为内置锁。线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁。获得内置锁的唯一途径就是进入这个锁的保护的同步代码块或方法。 互斥锁:内置锁是一个互斥锁,这就是意味着最多只有一个线程能够获得该锁,当线程A尝试去获得线程B持有的内置锁时,线程A必须等待或者阻塞

同步容器

99封情书 提交于 2019-11-28 20:15:57
同步容器 为了解决并发情况下的容器线程安全问题的。给多线程环境准备一个线程安全的容器对象。   线程安全的容器对象: Vector, Hashtable。线程安全容器对象,都是使用synchronized方法实现的。而concurrent包中的同步容器,大多数是使用系统底层技术实现的线程安全。类似native。Java8中使用CAS。 Map/Set ConcurrentHashMap / ConcurrentHashSet 底层哈希实现的同步Map(Set)。效率高,线程安全。使用系统底层技术实现线程安全。 量级较synchronized低。key和value不能为null。 --ConcurrentSkipListMap/ConcurrentSkipListSet 底层跳表(SkipList)实现的同步Map(Set)。有序,效率比ConcurrentHashMap稍低。 List 写时复制集合。写入效率低,读取效率高。每次写入数据,都会创建一个新的底层数组。 --CopyOnWriteArrayList Queue ArrayBlockingQueue 底层数组实现的有界队列。自动阻塞。根据调用API(add/put/offer)不同,有不同特性。   当容量不足的时候,有阻塞能力。    add方法 :在容量不足的时候,抛出异常。    put方法 :在容量不足的时候

java基础系列之多线程

≯℡__Kan透↙ 提交于 2019-11-28 20:13:33
之前对多线程这块一直不是很懂,现在看了一端时间的书与资料,写一些自己的心得体会吧 并发与并行 并行(parallel):指在同一时刻,有多条指令在多个处理器上同时执行。所以无论从微观还是从宏观来看,二者都是一起执行的。 并发(concurrency):指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。 打个比方:并行就是一个乐队在同一时间一起演奏 , 并发 就是一个人很短的时间内又弹钢琴又打鼓,只不过是他速度很快,感觉有多个人在演奏而已; 线程与进程 进程:运行中的应用程序称为进程,拥有系统资源(cpu、内存) 线程:进程中的一段代码,一个进程中可以有多段代码。本身不拥有资源(共享所在进程的资源),线程是最小的执行单元,每个进程都至少拥有一个线程; 在java应用程序来说,一个web 服务就是一个进程,在linux 系统中,当程序开启时,我们需要手动 或自动的给它分配内存空间,是因为它其中的线程需要这些(程序计数器,堆区,栈区等等)才能跑起来。 关闭时,我们可以通过对应的命令来关闭它,那它所拥有的系统资源就会释放,它的线程也会停止。 举个栗子 公司=进程 ,码农=线程; 在公司中,我们敲代码需要公司提供办公地点工具(电脑,座位,工资等等)

[c++11]多线程编程(三)——竞争条件与互斥锁

泄露秘密 提交于 2019-11-28 19:27:04
文章目录 竞争条件 使用互斥元保护共享数据 为保护共享数据精心组织代码 接口设计中也存在竞争条件 竞争条件 并发代码中最常见的错误之一就是竞争条件(race condition)。而其中最常见的就是数据竞争(data race),从整体上来看,所有线程之间共享数据的问题,都是修改数据导致的,如果所有的共享数据都是只读的,就不会发生问题。但是这是不可能的,大部分共享数据都是要被修改的。 而 c++ 中常见的 cout 就是一个共享资源,如果在多个线程同时执行cout,你会发发现很奇怪的问题: # include <iostream> # include <thread> # include <string> using namespace std ; // 普通函数 无参 void function_1 ( ) { for ( int i = 0 ; i > - 100 ; i -- ) cout << "From t1: " << i << endl ; } int main ( ) { std : : thread t1 ( function_1 ) ; for ( int i = 0 ; i < 100 ; i ++ ) cout << "From main: " << i << endl ; t1 . join ( ) ; return 0 ; }

C#多线程下如何保证线程安全?

送分小仙女□ 提交于 2019-11-28 19:16:57
多线程编程相对于单线程会出现一个特有的问题,就是线程安全的问题。所谓的线程安全,就是如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的。 线程安全问题都是由全局变量及静态变量引起的。 为了保证多线程情况下,访问静态变量的安全,可以用锁机制来保证,如下所示: 1 //需要加锁的静态全局变量 2 private static bool _isOK = false; 3 //lock只能锁定一个引用类型变量 4 private static object _lock = new object(); 5 static void MLock() 6 { 7 //多线程 8 new System.Threading.Thread(Done).Start(); 9 new System.Threading.Thread(Done).Start(); 10 Console.ReadLine(); 11 } 12 13 static void Done() 14 { 15 //lock只能锁定一个引用类型变量 16 lock (_lock) 17 { 18 if (!_isOK) 19 { 20 Console.WriteLine("OK"); 21 _isOK = true; 22 }