线程安全

第四篇:走近CopyOnWriteArrayList

跟風遠走 提交于 2020-01-28 18:46:14
CopyOnWriteArrayList简介 熟悉Java开发的童鞋都知道ArrayList是线程不安全的,在多线程的环境下可能会发生fast-fail机制,抛出ConcurrentModificationException异常,虽然也有并发容器Vector,或者采用Collections的synchronizedCollection方法将ArrayList包装成线程安全类,但是这两种方式都是利用synchronized关键字修饰方法,利用独占锁来保证线程安全,由于独占锁在同一时刻只有一个线程能够获取到对象监视器即读写操作不能并行,所以效率不高。而CopyOnWriteArrayList则采用CopyOnWrite的原理来实现的一个线程安全的容器,读写分离,效率高。 环境 本源码基于JDK1.8 fast-fail机制 fast-fail是一种快速失败机制,在容器中有广泛的运用,我们都知道ArrayList是线程不安全的,当多个线程同时对集合进行结构上的修改时,就可能会产生fast-fail机制。 例如:假设存在线程1,线程2,线程1通过Iterator对集合A进行遍历,线程2对集合A进行结构上的修改(不是仅仅修改一个元素),这时候就会产生fail-fast机制,抛出ConcurrentModificationException异常。 原因:线程对容器ArrayList进行修改时

jedis非线程安全

五迷三道 提交于 2020-01-28 13:35:11
网上都说jedis实例是非线程安全的,常常通过JedisPool连接池去管理实例,在多线程情况下让每个线程有自己独立的jedis实例,但都没有具体说明为啥jedis实例时非线程安全的,今天就让我们一探究竟吧! 1. jedis类图 jedis_note.png 2. 为什么jedis不是线程安全的? 由上述类图可知,Jedis类中有RedisInputStream和RedisOutputStream两个属性,而发送命令和获取返回值都是使用这两个成员变量,显然,这很容易引发多线程问题。测试代码如下: public class BadConcurrentJedisTest { private static final ExecutorService pool = Executors.newFixedThreadPool(20); private static final Jedis jedis = new Jedis("192.168.58.99", 6379); public static void main(String[] args) { for(int i=0;i<20;i++){ pool.execute(new RedisSet()); } } static class RedisSet implements Runnable{ @Override public void

单线程与多线程的区别,线程安全与线程不安全的区别

懵懂的女人 提交于 2020-01-28 12:00:47
线程安全与不安全的文章:https://blog.csdn.net/csdnnews/article/details/82321777 线程安全不等同于单线程,一般多个线程对同意方法或者语句进行写的时候要考虑线程安全问题,对结果没有影响的时候不用考虑 来源: CSDN 作者: weixin_38727482 链接: https://blog.csdn.net/weixin_38727482/article/details/103943307

Java学习(三)

对着背影说爱祢 提交于 2020-01-28 00:18:34
Java学习(三) 标签(空格分隔): Java 集合框架 java集合类主要有以下几种: List结构的集合类: ArrayList类,LinkedList类,Vector类,Stack类 Map结构的集合类: HashMap类,Hashtable类 Set结构的集合类: HashSet类,TreeSet类 Queue结构的集合 Queue接口 HashMap和Hashtable的区别 HashMap与Hashtable都是java的集合类,都可以用来存放java对象,这是他们的相同点,但是他们也有区别: 一、历史原因: Hashtable 是基于陈旧的Dictionary类的,HashMap是java1.2引进的Map接口的一个实现 二、同步性: Hashtable 是同步的,这个类中的一些方法保证了Hashtable中的对象是线程安全的,而HashMap则是异步的,因此HashMap中的对象并不是线程安全的,因为同步的要求会影响执行的效率,所以如果你不需要线程安全的集合那么使用HashMap是一个很好的选择,这样可以避免由于同步带来的不必要的性能开销,从而提高效率 三、值:HashMap可以让你将空值作为一个表的条目的key或value但是Hashtable是不能放入空值的(null) ArrayList和Vector的区别

线程安全与锁优化

你说的曾经没有我的故事 提交于 2020-01-27 16:42:25
1.线程安全: 当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方法进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象就是线程安全的。 2.Java语言中的线程安全  根据线程安全的安全程度由强到弱来排序,我们可以把Java语言中各种操作共享的数据分为以下5类:不可变、绝对线程安全、相对线程安全、线程兼容和线程对立。    1)不可变: 不可变的对象一定是线程安全的;Java语言中,如果共享数据是一个基本数据类型,那么只要在定义时使用final关键字修饰它就可以保证它是不可变的。如果共享数据是一个对象,那就需要保证对象的行为不会对其状态产生任何影响,即把对象中带有状态的变量都声明为final,这样在构造函数结束之后,它就是不可变的。    2)绝对线程安全: 就是一个类在任何运行时环境下,调用者都不需要任何额外的同步措施。在Java API中标注自己是线程安全的类,大多数都不是绝对线程安全的。    3)相对线程安全: 就是我们通常所讲的线程安全,它需要保证对这个对象单独的操作是线程安全的,我们在调用时不需要做额外的保障措施。但对于一些特定顺序的连续调用,就可能需要在调用端使用额外的同步手段来保证调用的正确性。    4)线程兼容: 指对象本身并不是线程安全的

多线程、死锁、线程安全、同步方法、代码块、休眠、守护线程、Thread、Runnable(二十三)

有些话、适合烂在心里 提交于 2020-01-27 10:31:31
1.多线程的引入 * 1.什么是线程   * 线程是程序执行的一条路径, 一个进程中可以包含多条线程   * 多线程并发执行可以提高程序的效率, 可以同时完成多项工作 * 2.多线程的应用场景   * 红蜘蛛同时共享屏幕给多个电脑   * 迅雷开启多条线程一起下载   * QQ同时和多个人一起视频   * 服务器同时处理多个客户端请求。 2.多线程并行和并发的区别 * 并行就是两个任务同时运行,就是甲任务进行的同时,乙任务也在进行。(需要多核CPU) * 并发是指两个任务都请求运行,而处理器只能按受一个任务,就把这两个任务安排轮流进行,由于时间间隔较短,使人感觉两个任务都在运行。 * 比如我跟两个网友聊天,左手操作一个电脑跟甲聊,同时右手用另一台电脑跟乙聊天,这就叫并行。 * 如果用一台电脑我先给甲发个消息,然后立刻再给乙发消息,然后再跟甲聊,再跟乙聊。这就叫并发。 3.Java程序运行原理和JVM的启动是多线程的吗 * A:Java程序运行原理   * Java命令会启动java虚拟机,启动JVM,等于启动了一个应用程序,也就是启动了一个进程。该进程会自动启动一个 “主线程” ,然后主线程去调用某个类的 main 方法。 * B:JVM的启动是多线程的吗   * JVM启动至少启动了垃圾回收线程和主线程,所以是多线程的。 4.多线程程序实现的方式 * 1.继承Thread

oo第二次博客作业

最后都变了- 提交于 2020-01-27 04:50:06
第五次作业——多线程电梯 作业概述:第五次作业是在第三次作业的基本上增加多线程的概念,说起来好像挺容易的,但其实真正做起来花费了很多时间,最先开始,我对于多线程的印象只有老师在课堂上讲的概念和简单的例子,所以要上网查找很多关于多线程的知识,然后从简单的实例锻炼开始学习。因为我第三次的电梯事实上是脑补实际情况再执行的,所以多线程的电梯需要重新构造,然后就从输入开始写,实现调度器,电梯,主函数,结束线程,将结果输入到文件中一步步实现功能,最后完成程序。真的是一个很漫长的过程,周一晚上才发现之前写的都不能用,真的很绝望,好在最后还是写出来了。 各类大致说明: Controller 类:调度器类,不断扫描请求队列,按照规定的调度方法将不同的指令分配给合适的电梯。 Elevator 类:第二次作业的电梯。 Floor 类:用于提供整个程序所需要使用的多种结构体 Queue 类: Floor结构的可变数组,用于完成队列增删、 get、 set等工作。 Request类:用于判断输入的字符串是否合法并返回一个值。 ALS类:构造了一个有当前可捎带队列和主请求的结构。 Scheduler类:第三次作业的电梯类,继承 Elevator类,但新生成了一个捎带函数用来完成电梯在捎带过程的工作。 Interface类:抽象接口,归纳 Elevator的所有方法。 MainClass类:主类

设计模式(一)单例模式

微笑、不失礼 提交于 2020-01-27 03:53:41
单例模式实现方式以及类加载 跳转到原文 本文主要介绍java的单例模式,以及详细剖析静态内部类之所以能够实现单例的原理。OK,废话不多说,进入正文。 首先我们要先了解下单例的四大原则: 1.构造私有。 2.以静态方法或者枚举返回实例。 3.确保实例只有一个,尤其是多线程环境。 4.确保反序列换时不会重新构建对象。 我们常用的单例模式有: 饿汉模式、懒汉模式、双重锁懒汉模式、静态内部类模式、枚举模式,我们来逐一分析下这些模式的区别。 1.饿汉模式: public class SingleTon{ private static SingleTon INSTANCE = new SingleTon(); private SingleTon(){} public static SingleTon getInstance(){ return INSTANCE; }} 饿汉模式在类被初始化时就已经在内存中创建了对象,以空间换时间,故不存在线程安全问题。 2.懒汉模式: public class SingleTon{ private static SingleTon INSTANCE = null; private SingleTon(){} public static SingleTon getInstance() { if(INSTANCE == null){ INSTANCE = new

c++设计模式-单例模式

送分小仙女□ 提交于 2020-01-26 23:45:25
定义 只提供唯一一个类的实例,具有全局变量的特点,在任何位置都可以通过接口获取到那个唯一实例 具体运用场景 1.设备管理器,系统中可能有多个设备,但是只有一个设备管理器,用于管理设备驱动; 2.数据池,用来缓存数据的数据结构,需要在一处写,多处读取或者多处写,多处读取; 要点 1.全局只有一个实例:static 特性,同时禁止用户自己声明并定义实例(把构造函数设为 private) 2.禁止赋值和拷贝 3.用户通过接口获取实例:使用 static 类成员函数 4.线程安全 实现 示例一、没有考虑线程安全的方式 class Singleton{ private: Singleton(){ //...... } Singleton(Singleton&); Singleton& operator=(const Singleton&); static Singleton* instance_ptr; public: ~Singleton(){ //..... } static Singleton* get_instance(){ if(instance_ptr==nullptr){ instance_ptr = new Singleton; } return instance_ptr; } }; Singleton* Singleton::instance_ptr = nullptr;

53JAVA多线程----线程安全

坚强是说给别人听的谎言 提交于 2020-01-26 19:43:46
1.线程安全 如果有多个线程在同时运行,而这些线程可能会同时运次这段代码。程序每次运行结果和单线程运行结果是一样的,而且其他的变量的值也和预期的结果是一样的,就是线程安全的。 下来通过一个案例,演示线程的安全问题: 电影院要卖票,我们模拟电影院的卖票过程,假设要播放的电影是“囧囧”,本次电影的座位共100个 我们来模拟电影院的售票窗口,实现多个窗口同时卖卖“囧囧”这场电影票(多个窗口一起卖这100张票) 需要窗口,采用线程对象来模拟;需要票,Runnable接口子类来模拟 模拟票 public class Ticket implements Runnable { private int ticket = 100 ; /* * 执行卖票操作 */ @Override public void run ( ) { //每个窗口卖票的操作 //窗口 永远开启 while ( true ) { if ( ticket > 0 ) { //有票 可以卖 //出票操作 //使用sleep模拟一下出票时间 try { Thread . sleep ( 100 ) ; } catch ( InterruptedException e ) { // TODO Auto‐generated catch block e . printStackTrace ( ) ; } //获取当前线程对象的名字