线程安全

单例模式、读写锁

喜夏-厌秋 提交于 2020-03-02 10:18:06
单例模式 是设计模式中的一种,是大佬们针对典型场景设计的解决方案。 典型场景:一个对象/一个资源 只能被初始化加载一次 。 例如:你在打游戏的时候,游戏有很多图片资源。希望一个图片只加载一次。 实现方式 : 饿汉/懒汉 饿汉:所有资源在程序初始化阶段 一次性 完成初始化(资源在初始化的时候一次性全部加载,后续只需要使用就可以) template<class T> class single { static T _data;//所以实例化的对象共用同一份资源 T* get_instance() { return &_data; } } 资源初始化的时候会慢一点,但是运行起来以后,会很流畅。 懒汉:资源在 使用的时候 进行初始化(用到的时候再去加载,当然也要保证只加载一次) template <typename T> class Singleton { static T* inst; public: static T* GetInstance() { if (inst == NULL) { inst = new T(); } return inst; } } 在使用的时候加载一次资源,会涉及到线程安全问题。(volatile、static、mutex、二次判断) 使用static保证多个对象使用 同一份 空间资源。(保证资源只被加载一次,实现单例模式) 加锁保护资源申请过程

OO第二单元总结

ぃ、小莉子 提交于 2020-03-02 08:30:45
概述: 第二单元的主要内容是通过编写多线程程序来模拟电梯的运行。第一次作业是单傻瓜电梯,不考虑策略,基本是初步了解多线程程序的编写;第二次作业是单ALS电梯,在上一次的基础上要实现捎带,尽可能在最短时间内完成所有请求;第三次作业是多电梯,每个电梯可停的层和容量都不同,需要考虑乘客换乘的情况。在这三次作业中,我们的程序需要使用不同的策略将线程安全贯彻始终,以免出现与期望不符的BUG,我认为这也是多线程程序编程中的重点所在。 一、程序分析 1、第一次作业 (1) 设计策略    第一次作业要实现一个傻瓜电梯,思路很简单,可以看作一个传统的生产者-消费者的问题。考虑一个输入线程作为生产者,电梯线程作为一个消费者,维护一个线程安全的共享队列作为托盘(这里我使用了JDK自带的ConcurrentLinkedQueue)。输入线程每次向队列输入请求,无请求时结束;电梯线程的调度策略就是每次从队列中取出一个请求来完成,当队列为空且输入线程结束时结束。 (2) 度量分析 代码规模 类图 复杂度分析   本次作业需求比较简单,所以方法的复杂度都不高,最高就是5。 协作图 SOLID原则    本次作业输入线程只负责输入,电梯线程负责运行和输出,调度器作为共享对象被前二者共享,符合单一责任原则(SRP)。其他原则个人认为由于本次作业要求都无需考虑。 (3) BUG分析   

HashMap原理分析及性能优化

╄→гoц情女王★ 提交于 2020-03-01 22:17:36
文章目录 一.HashMap是什么 二.HashMap继承类对比分析 三.HashMap源码相关单词含义 四.HashMap如何确定哈希桶数组索引位置 五. HashMap 的 put 方法分析 六.HashMap扩容机制 七.HashMap线程安全性 一.HashMap是什么 HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型。 HashMap是一个用于存储Key-Value键值对的集合,每一个键值对也叫做Entry。 这些个键值对(Entry)分散存储在一个数组当中,这个数组就是HashMap的主干。 数据结构(JDK1.8): Node<K,V>[] table; 数组+链表+红黑树 二.HashMap继承类对比分析 Java为数据结构中的映射定义了一个接口java.util.Map,此接口主要有四个常用的实现类,分别是 HashMap、Hashtable、LinkedHashMap和TreeMap , 类继承关系如下图所示: ① HashMap :它 根据键的hashCode值存储数据 ,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。 HashMap最多只允许一条记录的键为null,允许多条记录的值为null。 HashMap非线程安全 ,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致

windows(X64)下安装apche2.4+php7.2+mysql5.7

ⅰ亾dé卋堺 提交于 2020-03-01 21:48:22
一、首先安装Apache   1、在 https://www.apachelounge.com/download/ 下载httpd-2.4.32-Win64-VC15.zip包   2、解压到指定的安装目录(自己定),我解压到的是"D:/Apapch24"   3、在解压后的文件夹中有一个叫conf的文件夹,用编辑器打开conf文件夹下的httpd.conf文件,将文件中的有“C:/”的地方全部换成自己指定的安装目录,如下                       4、以管理员身份运行cmd(在system32文件夹中找到cmd.exe文件,右键,点击以管理员身份运行)     进入bin目录     >d:    >cd apache24/bin    >httpd -k install (将apache加入到windows服务中)    >httpd -k start (开启)    >httpd -k start (停止)    >httpd -k restart (重启)   5、打开浏览器,输入http://127.0.0.1 如果看到了It Works,说明Apache已经启动 二、安装php   1、在 https://windows.php.net/download#php-7.2 下载.zip包(如果是apache就选择ts的)(php-7.2.3-Win32

单例设计模式实现总结

三世轮回 提交于 2020-03-01 19:16:29
单例模式的总体概述 单例模式,属于创建型模式,《设计模式》一书对它做了定义:保证一个类仅有一个实例,并提供一个全局访问点。 单例模式适用于无状态的工具类、全局信息类等场景。例如日志工具类,在系统中记录日志;假设我们需要统计网站的访问次数,可以设置一个全局计数器。 单例模式的优势有 在内存里只有一个实例,减少了内存开销; 可以避免对资源的多重占用; 设置全局访问点,严格控制访问。 单例模式的研究重点大概有以下几个: 构造私有,提供静态输出接口 线程安全,确保全局唯一 延迟初始化 防止反射攻击 防止序列化破坏单例模式 多种实现方式与比较 线程安全的饿汉模式 public class HungrySingleton { private final static HungrySingleton instance = new HungrySingleton(); private HungrySingleton() { } public static HungrySingleton getInstance() { return instance; } } 也可以通过静态代码块的形式实现。实现与静态常量基本相同,只是把实例化过程放到了静态代码块中。 private final static HungrySingleton2 instance; static { instance = new

HashMap和ConcurrentHashMap

大城市里の小女人 提交于 2020-03-01 09:36:03
目录 HashMap Java7中HashMap(数组+单向链表) ​ Java8中的HashMap(数组+链表+红黑树) ConcurrentHashMap Java7中的ConcurrentHashMap Java8中的ConcurrentHashMap(引入红黑树) HashMap HashMap 根据键的 hashCode 值存储数据 ,大多数情况下可以直接定位到它的值,因而具有很快 的访问速度,但遍历顺序却是不确定的。 HashMap 最多只允许一条记录的键为 null ,允许多条记 录的值为 null。 HashMap 非线程安全 ,即任一时刻可以有多个线程同时写 HashMap,可能会导 致数据的不一致。 如果需要满足线程安全, 可以用 Collections 的 synchronizedMap 方法使 HashMap 具有线程安全的能力 ,或者 使用 ConcurrentHashMap 。 Java7中HashMap(数组+单向链表) 大方向上, HashMap 里面是一个 数组 ,然后数组中每个元素是一个 单向链表 。上图中,每个绿色 的实体是嵌套类 Entry 的实例, Entry 包含四个属性: key, value, hash 值和用于单向链表的 next 。 1. capacity:当前数组容量,始终保持 2^n,可以扩容,扩容后数组大小为当前的 2 倍。

刨根问底-ThreadLocal线程安全

孤人 提交于 2020-02-29 09:17:30
1、线程安全,值得是在多线程环境先,一个类在执行某个方法时,对类的内部实例变量的访问时安全的。因此,对于下面列出来的2类变量,不存在任何线程安全的说法: (1)方法签名中的任何参数变量 (2)处于方法内部的局部变量 线程安全针对于类内部的全局变量 2、java.lang.ThreadLocal类是jdk提供一种解决多线程并发问题方案。 ThreadLocal类在维护变量时,实际使用了当前线程Thread中的一个叫做ThreadLocalMap的独立副本,每个线程可以独立修改属于自己的副本而不会相互影响,从而隔离了线程和线程,避免了线程访问实例变量发生冲突的问题。 TreadLocal本身并不是一个线程,而是通过操作当前线程中的一个内部变量来达到与其他线程隔离的目的。之所以叫TdreadLocal,表示了其操作的对象时线程的一个本地变量。 现在看Thread代码: public class Thread implements Runnable { ThreadLocal.ThreadLocalMap threadLocals = null; } ThreadLocalMap跟随者当前的线程而存在。不用的线程Thread,拥有不同的ThreadLocalMap的本地实例变量,这就是副本的含义。 ThreadLocal是如何操作ThreadLocalMAP的 : public class

[高并发Java 三] Java内存模型和线程安全

不想你离开。 提交于 2020-02-29 06:33:01
网上很多资料在描述Java内存模型的时候,都会介绍有一个主存,然后每个工作线程有自己的工作内存。数据在主存中会有一份,在工作内存中也有一份。工作内存和主存之间会有各种原子操作去进行同步。 下图来源于 这篇Blog 但是由于Java版本的不断演变,内存模型也进行了改变。本文只讲述Java内存模型的一些特性,无论是新的内存模型还是旧的内存模型,在明白了这些特性以后,看起来也会更加清晰。 1. 原子性 原子性是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其它线程干扰。 一般认为cpu的指令都是原子操作,但是我们写的代码就不一定是原子操作了。 比如说i++。这个操作不是原子操作,基本分为3个操作,读取i,进行+1,赋值给i。 假设有两个线程,当第一个线程读取i=1时,还没进行+1操作,切换到第二个线程,此时第二个线程也读取的是i=1。随后两个线程进行后续+1操作,再赋值回去以后,i不是3,而是2。显然数据出现了不一致性。 再比如在32位的JVM上面去读取64位的long型数值,也不是一个原子操作。当然32位JVM读取32位整数是一个原子操作。 2. 有序性 在并发时,程序的执行可能就会出现乱序。 计算机在执行代码时,不一定会按照程序的顺序来执行。 class OrderExample { int a = 0; boolean flag = false;

python线程安全管理模块queue

这一生的挚爱 提交于 2020-02-29 02:02:57
from queue import Queue 1. q = Queue(10) 创建一个最大容量为10的队列 2. q.put(x) 将x写入队列 3. q.empty() 判断队列是否为空 , 返回布尔值 4. q.qsize() 返回队列q的当前大小 5. q.full() 判断队列是否已满,返回布尔值 6. q.get() 将队列q的队首元素出队,返回这个元素值 来源: CSDN 作者: cyj5201314 链接: https://blog.csdn.net/cyj5201314/article/details/104562144

大四Java复习笔记之Java基础

落爺英雄遲暮 提交于 2020-02-28 22:47:26
一、static和final 学习Java那么久,好像自己就没有怎么用过final,所以对fianl的理解不够。final不但出现在变量的修饰里面,还可以出现在方法和类的修饰。final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。final方法锁定方法,子类不能覆盖修改方法,同时方法会高效。final变量final修饰的成员变量表示常量,只能被赋值一次,赋值后值无法改变,final是指引用的变量不能不能变,但是引用所指向的对象中的内容可以变,同时如果是null的final变量可以赋值一次。 二、一个“.java”文件可以包含多个类 可以有多个类,不过只能有一个“public”的类,而且名字跟文件名一致。 三、&和&& &和&&都可以作为逻辑运算的与的运算符。但是&&会出现短路功能,也就是说如果前面的条件不成立的时候,后面的条件不会执行,例如:(1==2&&j++>1)。 &还可以作为位运算,&表示按位与运算(相同位的两个数字都为1,则为1;若有一个不为1,则为0)。 四、integer和int int是Java的8种原始数据类型之一。Java为每个原始数据提供封装类,integer是Java为int提供的封装类。int的默认值是0,而integer的默认值是null。 五、Java中string的创建