线程安全

线程安全问题总结!

[亡魂溺海] 提交于 2019-12-02 15:11:20
转载内容: https://mp.weixin.qq.com/s/s5eVZhkPoJIrH3zy65CwZg 仅用于个人学习,如有侵权私信立删! 什么是进程 电脑中时会有很多单独运行的程序,每个程序有一个独立的进程,而进程之间是相互独立存在的。比如下图中的QQ、酷狗播放器、电脑管家等等。 什么是线程 进程想要执行任务就需要依赖线程。换句话说,就是进程中的最小执行单位就是线程,并且一个进程中至少有一个线程。 那什么是多线程?提到多线程这里要说两个概念,就是串行和并行,搞清楚这个,我们才能更好地理解多线程。 所谓串行,其实是相对于单条线程来执行多个任务来说的,我们就拿下载文件来举个例子:当我们下载多个文件时,在串行中它是按照一定的顺序去进行下载的,也就是说,必须等下载完A之后才能开始下载B,它们在时间上是不可能发生重叠的。 并行:下载多个文件,开启多条线程,多个文件同时进行下载,这里是严格意义上的,在同一时刻发生的,并行在时间上是重叠的。 了解了这两个概念之后,我们再来说说什么是多线程。举个例子,我们打开腾讯管家,腾讯管家本身就是一个程序,也就是说它就是一个进程,它里面有很多的功能,我们可以看下图,能查杀病毒、清理垃圾、电脑加速等众多功能。 按照单线程来说,无论你想要清理垃圾、还是要病毒查杀,那么你必须先做完其中的一件事,才能做下一件事,这里面是有一个执行顺序的。 如果是多线程的话

Java线程面试题 Top 50

白昼怎懂夜的黑 提交于 2019-12-02 12:48:21
1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速。比如,如果一个线程完成一个任务要100毫秒,那么用十个线程完成改任务只需10毫秒。Java在语言层面对多线程提供了卓越的支持,它也是一个很好的卖点。欲了解更多详细信息请 点击这里 。 2) 线程和进程有什么区别? 线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。更多详细信息请 点击这里 。 3) 如何在Java中实现线程? 在语言层面有两种方式。java.lang.Thread 类的实例就是一个线程但是它需要调用java.lang.Runnable接口来执行,由于线程类本身就是调用的Runnable接口所以你可以继承java.lang.Thread 类或者直接调用Runnable接口来重写run()方法实现线程。更多详细信息请 点击这里 . 4) 用Runnable还是Thread? 这个问题是上题的后续,大家都知道我们可以通过继承Thread类或者调用Runnable接口来实现线程,问题是,那个方法更好呢?什么情况下使用它?这个问题很容易回答

ListenerBus 事件总线

喜欢而已 提交于 2019-12-02 11:44:55
ListenerBus 事件总线 ListenerBus可以接收事件并将事件送到对应的事件监听器 源码清单和我的理解注释 ListenerBus源码中第一行,创建了一个线程安全的ArrayList——CopyOnWriteArrayList,之后添加、者删除事件等操作都在这个线程安全的ArrayList中执行 private [ spark ] val listeners = new CopyOnWriteArrayList [ L ] private [ spark ] trait ListenerBus [ L < : AnyRef , E ] extends Logging { // 创建一个线程安全的ArrayList private [ spark ] val listeners = new CopyOnWriteArrayList [ L ] /** * 往CopyOnWriteArrayList中添加监听器 */ final def addListener ( listener : L ) : Unit = { listeners . add ( listener ) } /** * 在CopyOnWriteArrayList删除监听器 */ final def removeListener ( listener : L ) : Unit = { listeners

线程安全

ぃ、小莉子 提交于 2019-12-02 10:47:41
同步代码块,同步方法,Lock接口 Object ojb=new Object(); 同步代码块: public void run(){ while(true){ synchronized (obj) { if(ticket>0){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() +"窗口卖了第"+ticket--+"张票"); } } } } synchronized(obj){aaaaa} 同步方法: aaa(); public synchronized void aaa(){aaaaaa} public void run(){ while(true){ sale(); } } //同步方法 public synchronized void sale(){ //可能发生安全问题的代码放进来 if(ticket>0){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread(

java集合之HashMap与ConcurrentHashMap的自我理解

情到浓时终转凉″ 提交于 2019-12-02 09:38:15
一、HashMap存在不理解的问题 HashMap 是如何确定数组下标,原码是使用 高位>>>16 并且进行(n-1) & hash操作。 二、ConcurrentHashMap 三、并发容器 ConcurrentHashMap:线程安全的HashMap的实现 ConcurrentSkipListSet:线程安全的TreeSet的实现 CopyOnWriteArrayList:线程安全且在读操作时无锁的ArrayList CopyOnWriteArraySet:基于CopyOnWriteArrayList,不添加重复元素 ArrayBlockingQueue:基于数组、先进先出、线程安全,可实现指定时间的阻塞读写,并且容量可以限制 LinkedBlockingQueue:基于链表实现,读写各用一把锁,在高并发读写操作都多的情况下,性能优于ArrayBlockingQueue 来源: https://www.cnblogs.com/fc520/p/11741440.html

ConcurrentSkipListMap/ConcurrentSkipListSet

亡梦爱人 提交于 2019-12-02 08:57:54
转关于ConcurrentSkipListMap 和 ConcurrentSkipListSet 的深度好文, 终于明白了skip List (跳表)的含义 http://www.cnblogs.com/skywang12345/p/3498634.html http://www.cnblogs.com/skywang12345/p/3498556.html ===== ConcurrentSkipListMap介绍 ConcurrentSkipListMap是线程安全的有序的哈希表,适用于高并发的场景。 ConcurrentSkipListMap和 TreeMap ,它们虽然都是有序的哈希表。但是,第一,它们的线程安全机制不同,TreeMap是非线程安全的,而ConcurrentSkipListMap是线程安全的。第二,ConcurrentSkipListMap是通过跳表实现的,而TreeMap是通过红黑树实现的。 关于跳表(Skip List),它是平衡树的一种替代的数据结构,但是和红黑树不相同的是,跳表对于树的平衡的实现是基于一种随机化的算法的,这样也就是说跳表的插入和删除的工作是比较简单的。 ConcurrentSkipListMap原理和数据结构 ConcurrentSkipListMap的数据结构,如下图所示: 说明 : 先以数据 “7,14,21,32,37,71

转:理解ThreadLocal

杀马特。学长 韩版系。学妹 提交于 2019-12-02 08:38:23
ThreadLocal是什么 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。 ThreadLocal很容易让人望文生义,想当然地认为是一个“本地线程”。其实,ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它命名为ThreadLocalVariable更容易让人理解一些。 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思。 线程局部变量并不是Java的新发明,很多语言(如IBM IBM XL FORTRAN)在语法层面就提供线程局部变量。在Java中没有提供在语言级支持,而是变相地通过ThreadLocal的类提供支持。 所以,在Java中编写线程局部变量的代码相对来说要笨拙一些,因此造成线程局部变量没有在Java开发者中得到很好的普及。 ThreadLocal的接口方法 ThreadLocal类接口很简单,只有4个方法,我们先来了解一下: void set(Object value)

竞态条件

丶灬走出姿态 提交于 2019-12-02 07:00:23
1.定义 由于不恰当的执行时序而出现不正确的结果. 最常见的类型是 "先检查后执行"; 比如两个线程同时操作一个变量.我们定义一个 变量 int i = 0; 给 i 增加1; 增加1的过程有三个操作"读取-修改-写入",结果状态依赖于之前的状态. 但是在多线程情况下,这个状态依赖会被别的线程所修改,也就是说一个线程读取了 i = 0; 然后修改为 i = i + 1; 修改过程依赖的是之前读取 i = 0 的结果, 但是如果 i = 0 被别的线程所修改, 我们就可以说这就是出现了竞态条件,因为 : 我们这个操作基于了可能失效的观察结果来做出判断或执行某个计算,这也是竞态条件的本质, 多线程条件下状态依赖会被修改. 2.解决: 在明白了问题的发生后,解决就比较容易,"读取-修改-写入"让这一组操作变为原子操作就可以,要么都执行,要么都不执行,在没有执行完的时候加锁,让别的线程在没有获取锁的情况下阻塞,也就达到了线程安全的目的. 和事务类似,都是要么都执行,要么都不执行,使用了相同的思想.典型应用就是 synchronized 关键字 以及 通过 Atomic变量来控制状态来创建线程安全的类,因为线程安全的类在多线程条件下一定是线程安全的. 来源: https://www.cnblogs.com/lishuaiqi/p/11735684.html

谈谈你对多线程同步机制的理解?

风流意气都作罢 提交于 2019-12-02 06:40:09
线程同步是为了确保线程安全,所谓线程安全指的是多个线程对同一资源进行访问时,有可能产生数据不一致问题,导致线程访问的资源并不是安全的。 ( 如果多线程程序运行结果和单线程运行的结果是一样的,且相关变量的值与预期值一样,则是线程安全的。 ) java中与线程同步有关的关键字/类包括: volatile、synchronized、Lock、AtomicInteger等concurrent包下的原子类。。。等 线程安全 概述:当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象是线程安全的。 注: 这意味着如若要实现线程安全,代码本身必须要封装所有必要的正确性保障手段(比如锁的实现),以确保程序无论在多线程环境下如何调用该方法,将始终保持返回正确的结果。 Java的线程安全 我们在讨论Java的线程安全,实际上讨论的是“相对线程安全”。需要保证的是单独对象操作是线程安全的,调用过程中不需要额外的保障措施,但是涉及到某些业务场景需要特定顺序连续调用,就可能需要调用者考虑使用额外的同步手段保证同步。 例如使用 : synchronized Java中与线程同步有关的关键词/类: 1. Synchronized 同步原理 :

线程总结

与世无争的帅哥 提交于 2019-12-02 06:38:35
1.明确进程和线程的概念: 进程: 线程: 2.线程的特点: 并发性: 随机性: 通道性: 3.在java中只有Thread类代表线程 4.在java中使用线程的方式(在java中常见的创建线程的方式) 继承Thread类 实现Runnable接口 实现Callable接口 使用线程池 使用中间插件 4.1 继承Thread类 编写自定义类继承Thread类 创建自定义类的对象 把使用线程完成的业务代码编写到run方法中 调用Thread类的start方法,启动线程 4.2 实现Runnable接口 为什么要使用实现实现Runnable接口的方式创建线程? 如果自定义的类已经有了父类,则不能使用4.1的方式创建线程 使用实现Runnable接口实际上是把线程和要处理的业务功能解耦合(当需要线程给业务服务时,直接调用Thread(Runnable target)) Runnable接口中只有一个方法需要我们实现,就是 run 方法,需要把要使用线程服务的业务代码放入 run 方法 4.3 实现Callable接口 Callable接口中只有一个方法需要我们实现 ,就是 call 方法,需要把要使用线程的业务代码放入 call 方法 使用Runnable接口 和 Callable接口 完成多线程编程的区别是什么 ? Runnable接口的 run 方法没有返回值 ,