线程安全

Java volatile关键字

半世苍凉 提交于 2019-12-27 05:22:21
Java volatile关键字 2013-03-27 15:29 89人阅读 评论 (0) 收藏 举报 1、什么是原子操作(atomic operation)? 原子操作是不需要synchronized. 所谓原子操作,是指不会被线程调度机制打断的操作。这种操作,一但开始,就一直运行到结束,中间不会有任何的context switch。 原子性不可能由软件单独保证--必须需要硬件的支持,因此是和架构相关的。 2、锁的作用 锁提供了两种主要特性:互斥(mutual exclusion)和可见性(visibility)。互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实 现对共享数据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据。可见性要更加复杂一些,它必须确保释放锁之前对共享数据 做出的更改对于随后获得该锁的另一个线程是可见的 —— 如果没有同步机制提供的这种可见性保证,线程看到的共享变量可能是修改前的值或 不一致的值,这将引发许多严重问题。 3、类型描述符volatile Java语言包含两种内在的同步机制:同步块synchronized(或方法 或者lock)和 volatile 变量。这些机制的提出都是为了线程安全。 Volatile 变量的同步性较差(但有时它更简单并且开销更低),Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的

单例模式

。_饼干妹妹 提交于 2019-12-27 02:21:23
一、概述 单例模式的 定义 就是 确保某一个类只有一个实例,并且提供一个全局访问点。 属于设计模式三大类中的 创建型模式 。 单例模式具有典型的三个 特点 : 只有一个实例。 自我实例化。 提供全局访问点。 二、优缺点 优点 :由于单例模式只生成了一个实例,所以能够节约系统资源,减少性能开销,提高系统效率,同时也能够严格控制客户对它的访问。 缺点 :也正是因为系统中只有一个实例,这样就导致了单例类的职责过重,违背了“单一职责原则”,同时也没有抽象类,这样扩展起来有一定的困难。 三、常见实现方式 常见的单例模式实现方式有五种: 饿汉式 、 懒汉式 、 双重检测锁式 、 静态内部类式 和 枚举单例 。而在这五种方式中 饿汉式 和 懒汉式 又最为常见。下面将一一列举这五种方式的实现方法: 饿汉式 : 线程安全 ,调用效率高。但是不能延时加载。示例: public class SingletonDemo1 { <span class="token comment">//线程安全的</span> <span class="token comment">//类初始化时,立即加载这个对象</span> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class=

非线程安全类的异步多线程安全模型

别等时光非礼了梦想. 提交于 2019-12-26 04:41:54
在项目中经常会遇到一些需要异步处理的(耗时长)并且线程不安全的对象在多线程模型中使用,封装了一个实用的线程模板,用于直接处理这类的事务。将该线程不安全的对象直接绑定到单个线程上,然后将一个外部处理函数压入队列,由该线程取出对象和处理函数调用。绑定的对象作为第一个参数传入处理函数中,其余入参依次传入函数的实参。 代码如下, 版本:c++14, 编译器:gcc 5.4 #include <thread> #include <iostream> #include <functional> #include <queue> #include <mutex> #include <condition_variable> #include <chrono> template<typename INSTANCE> class SafeThread { public: SafeThread(std::shared_ptr<INSTANCE> i) : instance(i) { worker = std::thread([this] { while(!this->stop) { std::function<void()> task; { std::unique_lock<std::mutex> lck(this->queue_mtx); this->condition.wait(lck, [this

Android Lint 代码提示之: StringBuilder 替换 StringBuffer

主宰稳场 提交于 2019-12-26 04:22:26
StringBuilder StringBuffer是Java的基础。 今天在Android lint代码的时候,发现了修改提示。记录下,作为总结。先看代码段: byte[] byteArray = inStr.getBytes(StandardCharsets.UTF_8); byte[] md5Bytes = md5.digest(byteArray); //下面这个hexValue,会提示建议改成StringBuilder类型 StringBuffer hexValue = new StringBuffer(); for (int i = 0; i < md5Bytes.length; i++) { int val = ((int) md5Bytes[i]) & 0xff; if (val < 16) { hexValue.append("0"); } hexValue.append(Integer.toHexString(val)); } return hexValue.toString(); 如上代码中的注释,建议改成StringBuilder。为何建议改成StringBuilder呢? 提示信息意思是:报告指出 所有被定义为java.lang.StringBuffer的变量,如果被定义为java.lang.StringBuilder ,应该是更加高效。java.lang

JAVA基础:ArrayList和LinkedList区别

99封情书 提交于 2019-12-26 03:47:23
1.ArrayList是实现了 基于动态数组 的数据结构,LinkedList基于 链表 的数据结构。 2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 3.对于在指定index位置新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 4.ArrayList中的操作不是线程安全的!所以,建议在单线程中才使用ArrayList,而在多线程中可以选择Vector或者CopyOnWriteArrayList。LinkedList线程安全的处理方法     方法一:List<String> list = Collections.synchronizedList(new LinkedList<String>());     方法二:将LinkedList全部换成ConcurrentLinkedQueue 为什么在创建ArrayList对象时要初始化默认容量?    其实就是为了避免扩容,ArrayList扩容方法,这里 ensureCapacityInternal 才是ArrayList内部调用的扩容方法 /** * 公有方法 */public void ensureCapacity(int minCapacity) { int minExpand = (elementData

Java集合List、Set、Map

╄→尐↘猪︶ㄣ 提交于 2019-12-25 17:57:39
集合是 java 基础中非常重要的一部分,同样也是 Java 面试中很重要的一个知识点。所以,给王小整理了这篇关于集合的文章。 1、接口继承关系以及实现 集合类存放于 Java.util 包中,主要有 3 种:set、list 和 map。 Collection:Collection 是集合 List、Set、Queue 的最基本的接口 Iterator:迭代器,可以通过迭代器遍历集合中的数据 Map:是映射表的基础接口 层次关系图: 2、List Java 的 List 是非常常用的数据类型。List 是有序的 Collection。Java List 一共三个实现类:分别是 ArrayList、Vector 和 LinkedList。 2.1、ArrayList ArrayList 是最常用的 List 实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要将已经有数组的数据复制到新的存储空间中。当从 ArrayList 的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。 2.2、Vector Vector 与 ArrayList 一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写 Vector

Java多线程整理(li)

那年仲夏 提交于 2019-12-25 01:57:38
目录: 1.volatile变量 2.Java并发编程学习 3. CountDownLatch用法 4. CyclicBarrier使用 5.BlockingQueue使用 6.任务执行器Executor 7.CompletionService使用 8.ConcurrentHashMap使用 9.Lock使用 一、 volatile变量   1.volatile原理:volatile的原理实际上是告诉处理器,不要把变量缓存在寄存器或者相对于其他处理器不可见的地方,而是把变量放在主存,每次读写操作都在主存上进行操作。另外,被申明为volatile的变量也不会与其它内存中的变量进行重排序。   2.volatile同步:volatile是同步的一个子集,只保证了变量的可见性,但是不具备原子特性。这就是说线程能够自动发现 volatile 变量的最新值。相对于同步而言,volatile的优势:a.简易性,可以像使用其他变量一样使用volatile变量;b.volatile变量不会造成线程阻塞; c. 如果读操作远远大于写操作,volatile 变量还可以提供优于锁的性能优势 。   3.正确使用volatile条件:对变量的写操作不依赖于当前值;该变量没有包含在具有其他变量的不变式中; /* * 对于第一条原则:对变量的写操作不依赖于当前值; * 虽然i++只有一条语句

Redis c++ client的选型

会有一股神秘感。 提交于 2019-12-24 21:29:41
redis client基础库选择 在有限的开发维护人员情况下,redis客户端库版本稳定对我们来说就显得非常重要了,选择使用人数较多的库在遇到问题时得到回复或获得解决问题的办法相对较多, redis官网 提供的redis client列表如下: 从列表中我们选择官方推荐的客户端hiredis作为我们的客户端基础库 redis c++ client选型 当我们确定了hiredis作为我们的客户端基础库时,我们就有了大致的选择方向,我们的基础框架平台采用tars框架,完全采用c++语言特性进行开发,所以在使用redis时,需要尽量满足c++的语言特性,并且针对业务模块,应该尽可能的易于使用。hiredis客户端库基于C语言进行开发,功能齐全,但针对c++来说,虽然也可以勉强使用,但需要付出很大代价来进行足够多的上层封装,这会增加我们的开发工作量。有没有直接针对C++的客户端呢?我们从redis的官方客户端列表中找到了针对C++的客户端列表如下: 从列表中我们选取了基于hiredis的客户端,并将各自的特点逐一进行介绍 c+redis+client: star 58 简单易用,仅包括两个文件,一个cpp一个hpp,较低复杂度 支持redis服务端为单节点,也支持redis服务端作为集群部署 支持pipeline 使用连接池,线程安全,自动重连 不支持windows

实现一个线程安全的计数器

谁说胖子不能爱 提交于 2019-12-24 18:38:33
package com.test; public class MySafeThread implements Runnable{ public static volatile int a; @Override public void run(){ while (true){ try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } MySafeThread.calc(); } } //计数 注意加锁sychronized private synchronized static void calc(){ if (a<1000){ a=++a; //现场名称与自增后的值 System.out.println(Thread.currentThread().getName()+":"+a); } } //开启五个线程进行计数 public static void main(String[] args) { for (int i=0;i<5;i++){ MySafeThread mySafeThread = new MySafeThread(); Thread t = new Thread(mySafeThread); t.start(); } } } 第二种方法: package com

java设计模式--单例模式

こ雲淡風輕ζ 提交于 2019-12-24 18:07:02
单例设计模式 Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点。 核心知识点如下: (1) 将采用单例设计模式的类的构造方法私有化(采用private修饰)。 (2) 在其内部产生该类的实例化对象,并将其封装成private static类型。 (3) 定义一个静态方法返回该类的实例。 /** * 方法一 * 单例模式的实现:饿汉式,线程安全 但效率比较低 */ public class SingletonTest { // 定义一个私有的构造方法 private SingletonTest() { } // 将自身的实例对象设置为一个属性,并加上Static和final修饰符 private static final SingletonTest instance = new SingletonTest(); // 静态方法返回该类的实例 public static SingletonTest getInstancei() { return instance; } } 方法一就是传说的中的饿汉模式 优点是:写起来比较简单,而且不存在多线程同步问题,避免了synchronized所造成的性能问题; 缺点是:当类SingletonTest被加载的时候,会初始化static的instance