线程安全

JUC

你。 提交于 2019-11-28 06:24:05
JUC 回顾 1 NIO主要内容:Buffer、Channel 2 非阻塞式网络编程 今天任务 1 volatile的使用 2 原子变量和CAS算法 3 Lock接口 4 并发集合 5 同步工具类 第一节 JUC 概述 在 Java 5.0 提供了 java.util.concurrent(简称JUC)包,在此包中增加了在并发编程中很常用的工具类, 用于定义类似于线程的自定义子系统,包括线程池,异步IO和轻量级任务框架;还提供了用于多线程上下文中的 Collection实现等。 第二节 volatile volatile:易变的,不稳定的 在并发编程中的三个特性: (1)互斥性(原子性) (2)内存可见性 (3)指令重排序 int b=20; int a=10; int c=a+b; volatile 关键字: 当多个线程进行操作共享数据时,可以保证内存中的数据是可见的;相较于 synchronized 是一种较为轻量级的同步策略; volatile 不具备"互斥性"; volatile 不能保证变量的"原子性"; synchronized和volatile的区别: (1)synchronized可以实现互斥性和内存可见性,不能禁止指令重排序。 (2)volatile可以实现内存可见性,禁止指令重排序,不能保证原子性。 案例演示:内存可见性 public class

swift实现线程安全的栈和队列

泄露秘密 提交于 2019-11-28 05:59:24
实现一个线程安全的栈 这里使用数组来存储栈的数据。不足之处在于本例中的Stack可以无限扩容,更好的是初始化时候指定一个最大容量,防止不断扩容申请内存导致内存不够的问题。这里的线程安全使用一个串行队列来保证,实际上也可以通过加锁或者信号量甚至自旋锁来解决。 struct Stack<Element> { private var items: [Element] private var queue = DispatchQueue(label: "StackOperationQueue") public init(capacity: Int = 10) { items = [Element]() items.reserveCapacity(capacity) } mutating public func push(item: Element) { queue.sync { items.append(item) } } mutating public func pop() -> Element? { var item: Element? queue.sync { item = items.removeLast() } return item } } 实现一个线程安全的队列 // 存储数据的双向链表节点 class DoubleLinkNode<Element> { var

java面试必知必会

╄→гoц情女王★ 提交于 2019-11-28 05:42:45
java面试必知必会 对比 Vector、ArrayList、LinkedList 有何区别 Hashtable、HashMap、TreeMap 有什么不同 Hashtable、HashMap、TreeMap心得 如何保证容器是线程安全的?ConcurrentHashMap 如何实现高效地线程安全? Java 提供了哪些 IO 方式? NIO 如何实现多路复用? Java 有几种文件拷贝方式?哪一种最高效? 谈谈接口和抽象类有什么区别? 面向对象设计 面向对象编程,掌握基本的设计原则S.O.L.I.D 原则 谈谈你知道的设计模式?请手动实现单例模式,Spring 等框架中使用了哪些模式? synchronized 底层如何实现?什么是锁的升级、降级? 免责声明 对比 Vector、ArrayList、LinkedList 有何区别 这三者都是实现集合框架中的 List,也就是所谓的有序集合,因此具体功能也比较近似,比如都提供按照位置进行定位、添加或者删除的操作,都提供迭代器以遍历其内容等。但因为具体的设计区别,在行为、性能、线程安全等方面,表现又有很大不同 Vector 是 Java 早期提供的线程安全的动态数组,如果不需要线程安全,并不建议选择,毕竟同步是有额外开销的。Vector 内部是使用对象数组来保存数据,可以根据需要自动的增加容量,当数组已满时,会创建新的数组

Java中String、StringBuffer、StringBuilder的区别(转)

浪尽此生 提交于 2019-11-28 05:41:46
Java中String、StringBuffer、StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题。现在总结一下,看看他们的不同与相同。 1.可变与不可变    String类中使用字符数组保存字符串,如下就是,因为有“final”修饰符,所以可以知道string对象是不可变的。      private final char value[];    StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,如下就是,可知这两种对象都是可变的。     char[] value; 2.是否多线程安全   String中的对象是不可变的,也就可以理解为常量, 显然线程安全 。   AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。   StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是 线程安全的 。看如下源码: public synchronized StringBuffer reverse() { super

Java面试题目

假装没事ソ 提交于 2019-11-28 04:08:37
String、StringBuffer与StringBuilder的区别 String 字符串常量 StringBuffer 字符串变量(线程安全) StringBuilder 字符串变量(非线程安全) 首先三者主要输在运行速度和线程安全这两位方面。 string:是一个java类,是一个字符串常量,声明是:public final ,所以final的话是改变不了的。字符串值改变不了,就只能在内存创建一个空间来保存新的字符串。所以一旦遇到复杂的操作,用string是多么低效率的事啊。 StringBuilder和StringBuffer有公共类AbstractStringBuilder(抽象类)。 1、执行速度上比较(快慢):stringbuilder>stringbuffer>string 原因(也就是变量和常量的关系):string为字符串常量,后两个是字符串变量,也就是说string对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。而不进行创建和回收,所以速度要比string快很多。 2、线程安全上比较:stringbuilder是线程不安全的,而stringbuffer是线程安全的。 原因:String:对象定义后,线程安全。 stringbuffer对象在字符串缓冲区被多个线程使用时

Java多线程-----线程安全及解决机制

人盡茶涼 提交于 2019-11-28 03:56:55
1.什么是线程安全问题? 从某个线程开始访问到访问结束的整个过程,如果有一个访问对象被其他线程修改,那么对于当前线程而言就发生了线程安全问题; 如果在整个访问过程中,无一对象被其他线程修改,就是线程安全的,即 存在两个或者两个以上的线程对象共享同一个资源 2.线程安全问题产生的根本原因 首先是多线程环境,即同时存在有多个操作者,单线程环境不存在线程安全问题。在单线程环境下,任何操作包括修改操作都是操作者自己发出的, 操作者发出操作时不仅有明确的目的,而且意识到操作的影响。 多个操作者(线程)必须操作同一个对象,只有多个操作者同时操作一个对象,行为的影响才能立即传递到其他操作者。 多个操作者(线程)对同一对象的操作必须包含修改操作,共同读取不存在线程安全问题,因为对象不被修改,未发生变化,不能产生影响。 综上可知,线程安全问题产生的根本原因是共享数据存在被并发修改的可能,即一个线程读取时,允许另一个线程修改 3.有线程安全的实例 模拟火车站售票窗口,开启三个窗口售票,总票数为20张 实例一: package com.practise.threadsafe; //模拟火车站售票窗口,开启三个窗口售票,总票数为100张 //存在线程的安全问题 class Window extends Thread { static int ticket = 20; public void run() {

容器之知识点总结

大城市里の小女人 提交于 2019-11-28 02:00:40
1.List,Set与Map List(有序可重复): List接口存储一组不唯一(可以有多个元素引用相同的对象),有序的对象 Set(无序不重复): 不允许重复的集合。不会有多个元素引用相同的对象。 Map(无序不重复): 使用键值对存储。Map会维护与Key有关联的值。两个Key可以引用相同的对象,但Key不能重复。 2.ArrayList与LinkedList 1. 是否保证线程安全: ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全; 2. 底层数据结构: Arraylist 底层使用的是 Object 数组 ; LinkedList 底层使用的是 双向链表 数据结构(JDK1.6之前为循环链表,JDK1.7取消了循环。注意双向链表和双向循环链表的区别!) 3. 插入和删除是否受元素位置的影响: ① ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。 比如:执行 add(E e) 方法的时候, ArrayList 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是O(1)。但是如果要在指定位置 i 插入和删除元素的话( add(int index, E element) )时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执行向后位

线程安全与非线程安全

五迷三道 提交于 2019-11-28 01:53:20
在java的线程中经常能看到关于线程安全与非线程安全的说法,以前我认为线程安全是必须的,但在我进行了关于进度条组件的编写时,发现线程安全并不是必需的。也许你会说在每次一个代码段执行完,要改变进度条时,调用一下进度条组件的刷新方法就行了。这样无疑使代码的执行时间大大增长了,代码的效率是我们必须重视的,而且1%的进度,在任务较多,代码执行时间长的情况下人眼是不能分辨的,而在任务比较少的情况下,整个进度条也许都是一闪而逝,更何况1%的进度。所以在这种不需要即时显示数据变化的情况下,线程不安全也是可以的,只有那些对数据的及时性非常看重的才需要注意线程安全。比如商品金额,你要即时的显示当前的金额,不能出现脏数据(无效数据,过时的数据),当金额变化时,其他线程会获取现在的金额数据进行处理,然而如果还没有处理完,金额又变了的话,就会出现脏数据。所以在处理中要禁止对金额数据的操作,即加锁。来保证线程安全。 来源: https://www.cnblogs.com/darling1550lz/p/11386507.html

深入理解并发编程(一):到底什么是线程安全

好久不见. 提交于 2019-11-28 01:10:54
什么是线程安全 维基百科: 线程安全是编程中的术语,指某个函数、函数库在 并发 环境中被调用时,能够正确地处理 多个线程 之间的 共享变量 ,使程序功能正确完成。 我们把这个定义拆解一下,我们需要弄清楚这么几点: 1、并发 2、多线程 3、共享变量 1 并发 提到线程安全,必须要提及的一个词那就是并发,如果没有并发的话,那么也就不存在线程安全问题了。 1.1 什么是并发 并发(Concurrent): 在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行。 那么,操作系统视如何实现这种并发的呢? 现在我们用到操作系统,无论是Windows、Linux还是MacOS等其实都是多用户多任务分时操作系统。使用这些操作系统的用户是可以“同时”干多件事的。 但是实际上,对于单CPU的计算机来说,在CPU中,同一时间是只能干一件事儿的。为了看起来像是“同时干多件事”, 分时操作系统是把CPU的时间划分成长短基本相同的时间区间,即”时间片”,通过操作系统的管理,把这些时间片依次轮流地分配给各个用户使用 。 如果某个作业在时间片结束之前,整个任务还没有完成,那么该作业就被暂停下来,放弃CPU,等待下一轮循环再继续做.此时CPU又分配给另一个作业去使用。 由于计算机的处理速度很快,只要时间片的间隔取得适当