线程安全

Java BlockingQueue

冷暖自知 提交于 2019-12-10 04:01:49
前言 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题。通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利。本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景。 认识BlockingQueue 阻塞队列,顾名思义,首先它是一个队列,而一个队列在数据结构中所起的作用大致如下图所示: 从上图我们可以很清楚看到,通过一个共享的队列,可以使得数据由队列的一端输入,从另外一端输出; 常用的队列主要有以下两种:(当然通过不同的实现方式,还可以延伸出很多不同类型的队列,DelayQueue就是其中的一种) 先进先出(FIFO) :先插入的队列的元素也最先出队列,类似于排队的功能。从某种程度上来说这种队列也体现了一种公平性。 后进先出(LIFO) :后插入队列的元素最先出队列,这种队列优先处理最近发生的事件。 多线程环境中,通过队列可以很容易实现数据共享,比如经典的“生产者”和“消费者”模型中,通过队列可以很便利地实现两者之间的数据共享。假设我们有若干生产者线程,另外又有若干个消费者线程。如果生产者线程需要把准备好的数据共享给消费者线程,利用队列的方式来传递数据,就可以很方便地解决他们之间的数据共享问题。但如果生产者和消费者在某个时间段内

正确使用 Volatile 变量

落爺英雄遲暮 提交于 2019-12-10 02:28:30
Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized ”;与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分。本文介绍了几种有效使用 volatile 变量的模式,并强调了几种不适合使用 volatile 变量的情形。 锁提供了两种主要特性: 互斥(mutual exclusion) 和 可见性(visibility) 。互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据。可见性要更加复杂一些,它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的 —— 如果没有同步机制提供的这种可见性保证,线程看到的共享变量可能是修改前的值或不一致的值,这将引发许多严重问题。 Volatile 变量 Volatile 变量具有 synchronized 的可见性特性,但是不具备原子特性。这就是说线程能够自动发现 volatile 变量的最新值。Volatile 变量可用于提供线程安全,但是只能应用于非常有限的一组用例:多个变量之间或者某个变量的当前值与修改后值之间没有约束。因此,单独使用 volatile 还不足以实现计数器

servlet映射,线程安全,servletconfig对象,servletcontext对象

▼魔方 西西 提交于 2019-12-09 23:21:18
Servlet映射细节: 映射代码体现: <servlet> <servlet-name>TextServlet1</servlet-name> <servlet-class>text.Servlet.TextServlet1</servlet-class> </servlet> <servlet-mapping> <servlet-name>TextServlet1</servlet-name> <url-pattern>/servlet/TextServlet1</url-pattern> </servlet-mapping> 映射可以使用通配符: 1 以*开头,以扩展名结尾:*.do 2 以/开头,/adc/* 匹配优先级:绝对优先级》/》* servlet中的线程安全问题: 当存在全局变量时,就会出现线程安全问题, 如果要使用全局变量,就要使用同步,代码运行的效率低下。 ServletConfig 对象用于获取配置参数: 配置参数代码: <servlet> <servlet-name>TextServlet1</servlet-name> <servlet-class>text.Servlet.TextServlet1</servlet-class> <init-param> <param-value>encoding</param-value> <param-value

图解 java线程安全

和自甴很熟 提交于 2019-12-09 21:18:36
什么是线程 线程安全 Java内存模型 - JMM 什么是 JMM 线程安全的本质 线程同步 Synchronized 关键字 Synchronized 作用 Volatile 关键字 Volatile 作用 java.util.concurrent.atomic Lock 详情参考 作者:七彩祥云至尊宝 https://juejin.im/post/5d2c97bff265da1bc552954b 来源: CSDN 作者: 轩辕朗 链接: https://blog.csdn.net/weixin_45805060/article/details/103464148

如何设计一个本地缓存?

时光怂恿深爱的人放手 提交于 2019-12-09 15:24:19
考虑点 考虑点主要在数据用何种方式存储,能存储多少数据,多余的数据如何处理等几个点,下面我们来详细的介绍每个考虑点,以及该如何去实现; 1.数据结构 首要考虑的就是数据该如何存储,用什么数据结构存储,最简单的就直接用Map来存储数据;或者复杂的如redis一样提供了多种数据类型哈希,列表,集合,有序集合等,底层使用了双端链表,压缩列表,集合,跳跃表等数据结构; 2.对象上限 因为是本地缓存,内存有上限,所以一般都会指定缓存对象的数量比如1024,当达到某个上限后需要有某种策略去删除多余的数据; 3.清除策略 上面说到当达到对象上限之后需要有清除策略,常见的比如有LRU(最近最少使用)、FIFO(先进先出)、LFU(最近最不常用)、SOFT(软引用)、WEAK(弱引用)等策略; 4.过期时间 除了使用清除策略,一般本地缓存也会有一个过期时间设置,比如redis可以给每个key设置一个过期时间,这样当达到过期时间之后直接删除,采用清除策略+过期时间双重保证; 5.线程安全 像redis是直接使用单线程处理,所以就不存在线程安全问题;而我们现在提供的本地缓存往往是可以多个线程同时访问的,所以线程安全是不容忽视的问题;并且线程安全问题是不应该抛给使用者去保证; 6.简明的接口 提供一个傻瓜式的对外接口是很有必要的,对使用者来说使用此缓存不是一种负担而是一种享受;提供常用的get,put

如何正确地写出单例模式

こ雲淡風輕ζ 提交于 2019-12-09 13:39:33
单例模式算是设计模式中最容易理解,也是最容易手写代码的模式了吧。但是其中的坑却不少,所以也常作为面试题来考。本文主要对几种单例写法的整理,并分析其优缺点。很多都是一些老生常谈的问题,但如果你不知道如何创建一个线程安全的单例,不知道什么是双检锁,那这篇文章可能会帮助到你。 懒汉式,线程不安全 当被问到要实现一个单例模式时,很多人的第一反应是写出如下的代码,包括教科书上也是这样教我们的。 public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } } 这段代码简单明了,而且使用了懒加载模式,但是却存在致命的问题。当有多个线程并行调用 getInstance() 的时候,就会创建多个实例。也就是说在多线程下不能正常工作。 懒汉式,线程安全 为了解决上面的问题,最简单的方法是将整个 getInstance() 方法设为同步(synchronized)。 public static synchronized Singleton getInstance() { if

【PHP】高级面试题之十万个为什么?(二)

一曲冷凌霜 提交于 2019-12-09 06:32:37
成功不是将来才有的,而是从决定去做的那一刻起,持续累积而成。 1、处理PHP数组,foreach和for那个效率更高?效率高的原因是什么呢? 答:foreach的效率更高,因为foreach走的是链表的遍历,详细解释请查看另外一篇文章“for和foreach那个效率更高?原因是什么?” for和foreach那个效率更高? 2、PHP数组底层采用的是循环链表,正向、反向遍历数组都很方便是否正确呢? 答:这个说话是错误的,php数组是双向链表,故而可以正向、反向遍历数组 什么是链表呢? 链表是一种经常被使用的一种数据结构。链表中的每一个元素都至少有两个元素,一个指向它的下一个元素,一个用来存放它自己的数据——>我们称之为单项链表,缺点是每次查询都需要从开始位置开始一次像下找。 后来加了一个元素指向前一个元素,这样我们不管知道链表中哪一个元素,我们都能正向、反向的查到所有的元素(php数组就是这样)——>双向链表 3、PHP数组插入和删除操作的时间复杂度都是O(1)? 答:我们可以用一个整数来当作下标去数组中取出我们想要的数据,就像var_dump()的实现中通过args[i]来获取参数并把它传递给php_var_dump()函数那样。使用数组最大的好处便是速度!读写都可以在O(1)内完成,因为它每个元素的大小都是一致的,只要知道下标,便可以瞬间计算出其对应的元素在内存中的位置

C#集合类型总结和性能分析

假如想象 提交于 2019-12-09 05:41:14
C#集合类型概述 集合是.NET FCL(Framework Class Library)中很重要的一部分。所有的集合类都继承自 IEnumerable 。集合类总体可分为一下几类:关联/非关联型集合,顺序/随机访问集合,顺序/无序集合,泛型/非泛型集合,线程安全集合。 各集合类底层接口关系图 泛型与非泛型集合类的分析 泛型集合是类型安全的 ,基于固定的泛型T,运行时不需要像非泛型的执行Object和具体类型的类型转换。 泛型集合的效率相对较高。 两者都能实现数据存储,不同的是泛型只能存放T类型数据,有运行时检测,而非泛型的都转化为Object存储,能存储任意类型,包括值类型,会带来装箱拆箱的性能损耗,同时都是Object类型(弱类型)编译时无法类型检测,运行时会导致类型不一致的安全性问题。 具体接口/类分析 CollectionBase/DictionaryBase的目的 都是抽象类,不能实例化; 目的是提供给用户自定义实现强类型的集合,解决一般非泛型集合的弱类型不安全的问题。 IEnumerator/IEnumerable IEnumerator定义了我们遍历集合的基本方法,以便我们可以实现单向向前的访问集合中的每一个元素。 所有的集合类都继承了IEnumerator接口,包括String类。 而IEnumerable只有一个方法GetEnumerator即得到遍历器。

servlet不是线程安全的

半世苍凉 提交于 2019-12-08 09:46:30
在tomcat容器中,servlet默认是单例模式;如果实现ISingleThreadModule标记接口 则针对多个请求创建多个实例(最多20个),为了实现线程安全,可以: 1.使用局部变量 而不是实例变量 2.使用synchronized关键字 综上说明静态变量、实例变量、局部变量,三者使用范围或者说生命周期越大 则越不线程安全 来源: https://www.cnblogs.com/hzq3554055/p/12004630.html

蚂蚁金服、字节跳动、PDD社招面经Java岗(分布式+线程安全+MySQL+CAS)

情到浓时终转凉″ 提交于 2019-12-07 22:05:00
拿了蚂蚁和pdd的offer,写下面经 蚂蚁金服 一面 算法题,给了长度为N的有重复元素的数组,要求输出第10大的数。 需要在2小时内完成。 二面 自我介绍 目前在部门做什么,业务简单介绍下,内部有哪些系统,作用和交互过程说下 Dubbo踩过哪些坑,怎么解决的? 对线程安全的理解 乐观锁和悲观锁的区别? 这两种锁在Java和MySQL分别是怎么实现的? 事务有哪些特性? 怎么理解原子性? HashMap为什么不是线程安全的? 怎么让HashMap变得线程安全? jdk1.8对ConcurrentHashMap做了哪些优化? redis主从机制了解么?怎么实现的? 有过GC调优的经历么? 有什么想问的 三面 自我介绍 接下来就是全部问的项目,对自己的项目细节逐个盘问,最后问了下如何改进方案 有什么想问我么? 四面 介绍下自己 问项目 说说Spring的生命周期吧 说说GC的过程 强制young gc会有什么问题? 知道G1么? 回收过程是怎么样的? 你提到的Remember Set底层是怎么实现的? CMS GC有什么问题? 怎么避免产生浮动垃圾? 有什么想问的么? 五面 HRBP面,主要聊了部门在做的事情、职业发展、福利待遇等。阿里面试官有一票否决权,很看重你的价值观是否match。 HR面一定要诚实,不要说谎,只要你说谎HR都会去证实。 最后HR还对我说目前稳定性保障部挺缺人的