线程安全

三、单例模式

亡梦爱人 提交于 2019-12-04 17:29:35
单例模式 前言 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。 注意: 1、单例类只能有一个实例。 2、单例类必须自己创建自己的唯一实例。 3、单例类必须给所有其他对象提供这一实例。 单例模式的几种实现方式 【1】懒汉式(线程不安全) public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } } 这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。 这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。 【2】懒汉式(线程安全) public class Singleton {

线程安全之ConcurrentQueue<T>队列

走远了吗. 提交于 2019-12-04 16:42:05
  最近在弄一个小项目,大概600w行的数据,要进行数据清洗,因数据量偏大,如果单线程去执行,会造成效率偏低,只能用多线程了,但采用多线程存在线程安全问题,于是查了下资料,发现有ConcurrentQueue<T>该数据结构,完美的解决了我目前问题。   采 自msdn上面解释:表示线程安全的先进先出 (FIFO) 集合。 先说说简单的用法吧:(来自msdn)   1.Enqueue(T) 将对象添加到 ConcurrentQueue<T> 的结尾处。   2.TryDequeue(T) 尝试移除并返回位于并发队列开头处的对象。   3.Count 获取 ConcurrentQueue<T> 中包含的元素数   4.IsEmpty 获取一个值,该值指示 ConcurrentQueue<T> 是否为空。 下面是小项目的实现方案,采用最简单的方式(生产者/消费者模式),先将数据写入到队列中,再由消费者进行消费,以下是我写的一个小Demo,用于学习,不对的地方请各位多多指教! using System; using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; namespace ThreadCQueue { class Program { static void

Java多线程之线程安全队列Queue

巧了我就是萌 提交于 2019-12-04 15:58:35
在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列。Java提供的线程安全的Queue可以分为 阻塞队列和非阻塞队列 ,其中阻塞队列的典型例子是BlockingQueue,非阻塞队列的典型例子是ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列。 注:什么叫 线程安全 ?这个首先要明确。 线程安全的类 ,指的是 类内共享的全局变量的访问必须保证是 不受多线程形式影响的 。如果由于多线程的访问(比如修改、遍历、查看)而使这些变量结构被破坏或者针对这些变量操作的原子性被破坏,则这个类就不是线程安全的。 今天就聊聊这两种Queue,本文分为以下两个部分,用分割线分开: BlockingQueue 阻塞算法 ConcurrentLinkedQueue,非阻塞算法 首先来看看 BlockingQueue : Queue是什么就不需要多说了吧,一句话: 队列是先进先出 。相对的, 栈是后进先出 。如果不熟悉的话先找本基础的数据结构的书看看吧。 BlockingQueue,顾名思义,“阻塞队列”:可以提供阻塞功能的队列。 首先,看看BlockingQueue提供的常用方法: 可能报异常 返回布尔值 可能阻塞 设定等待时间 入队 add(e) offer(e) put(e) offer(e, timeout, unit)

java中的线程安全

馋奶兔 提交于 2019-12-04 15:08:18
在Java中,线程的安全实际上指的是内存的安全,这是由操作系统决定的。 目前主流的操作系统都是多任务的,即多个进程同时运行。为了保证安全,每个进程只能访问分配给自己的内存空间,而不能访问别的、分配给别的进程的内存空间,这一安全特性是由操作系统保障的。但是线程却与进程不同,因为在每个进程的内存空间中都会有一块特殊的公共区域,通常被称为堆(内存),这块内存区域是进程内所有的线程都可以访问得到的,这个特性是线程之间通信的一种方式,但是却会引发多个线程同时访问一块内存区域可能产生的一系列问题,这些问题被统称为线程的安全问题。 如何在Java中保证线程安全,也就是保证内存的安全,是一个重要的知识点。 使用局部变量保证线程安全(内存隔离法) 在程序中,操作系统会为每个线程分配专属的内存空间,通常被称为栈内存。栈内存是当前线程所私有的,其它线程无权访问,这是由操作系统保障的。那么,如果想要一些数据只能被某个线程访问的话,就可以把这些数据放入线程专属的栈内存中,其中最常见的就是局部变量,局部变量在线程执行方法时被分配到线程的栈内存中。 double avgScore(double[] scores) { double sum = 0; for (double score : scores) { sum += score; } int count = scores.length; double

Java多线程

坚强是说给别人听的谎言 提交于 2019-12-04 11:53:55
1. 多线程 image.png 新建状态: 一个新产生的线程从新状态开始了它的生命周期。它保持这个状态直到程序 start 这个线程。 运行状态:当一个新状态的线程被 start 以后,线程就变成可运行状态,一个线程在此状态下被认为是开始执行其任务 就绪状态:当一个线程等待另外一个线程执行一个任务的时候,该线程就进入就绪状态。当另一个线程给就绪状态的线程发送信号时,该线程才重新切换到运行状态。 休眠状态: 由于一个线程的时间片用完了,该线程从运行状态进入休眠状态。当时间间隔到期或者等待的时间发生了,该状态的线程切换到运行状态。 终止状态: 一个运行状态的线程完成任务或者其他终止条件发生,该线程就切换到终止状态。 2. 僵死进程 计算机的计算模型大部分是基于空间和时间来考虑的。僵死进程唯一占用的空间是pid空间,这个空间如果不能合理的应用就会造成浪费,之所以保留这个空间,是为了让父进程感知子进程已经终止这个行为。时间方面,这个感知过程是一个异步的过程。 3. 创建线程的方式 继承 Thread 类 实现 Runnable 接口 使用 Executor 框架 法一:继承Thread类 1.1定义一个类继承Thread 1.2重写run方法 1.3创建对象 1.4调用start方法开启线程 线程对象调用run()方法和start()方法区别? 调用run方法不开启线程,仅是对象调用方法

.NET 中的Dictionary HashTable 与 ConcurrentDictionary的区别

戏子无情 提交于 2019-12-04 08:28:14
共同点: 都是基于 Key-Value 形式的存储数据的集合 区别: Dictionary : 优点: 支持泛型,是类型安全的。即: Dictionary<TKey,TValue>, 可以减少类型转换,减少内存的消耗 缺点: 线程不安全,多线程同时访问一个Dictionary时可能会出现数据错乱。 HashTable: 优点:线程安全 缺点:不是类型安全的, hashTable<object,object>, 需要类型转换 ConcurrentDictionaey: 优点: 支持泛型,并且线程安全 参考链接:https://blog.csdn.net/yinghuolsx/article/details/72952857 运行效率对比图: 来源: https://www.cnblogs.com/Echolh/p/11848402.html

java基础常见面试题

牧云@^-^@ 提交于 2019-12-04 07:53:29
1.八种基本数据类型的大小,以及他们的封装类。 2.equals与==的区别 使用==比较原生类型如:boolean、int、char等等,使用equals()比较对象。 (1)==是判断两个变量或实例是不是指向同一个内存空间。 equals是判断两个变量或实例所指向的内存空间的值是不是相同。 (2)==是指对内存地址进行比较。 equals()是对字符串的内容进行比较。 (3)==指引用是否相同。 equals()指的是值是否相同。 3.HashCode的特性 https://blog.csdn.net/seu_calvin/article/details/52094115 (1)HashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,HashCode经常用于确定对象的存储地址; (2)如果两个对象相同, equals方法一定返回true,并且这两个对象的HashCode一定相同; (3)两个对象的HashCode相同,并不一定表示两个对象就相同,即equals()不一定为true,只能说明这两个对象在一个散列存储结构中。 (4)如果对象的equals方法被重写,那么对象的HashCode也尽量重写。 如何理解HashCode的作用: 从Object角度看,JVM每new一个Object,它都会将这个Object丢到一个Hash表中去,这样的话

单例设计模式

别等时光非礼了梦想. 提交于 2019-12-04 07:18:45
所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类 只能存在一个对象实例 ,并且该类只提供一个取得其对象实例的方法(静态方法)。 比如Hibernate的SessionFactory,它充当数据存储源的代理,并负责创建Session对象。SessionFactory并不是轻量级的,一般情况下,一个项目通常只需要一个SessionFactory就够,这是就会使用到单例模式。 单例模式有八种方式: 1、饿汉式(静态常量) 2、饿汉式(静态代码块) 3、懒汉式(线程不安全) 4、懒汉式(线程安全,同步方法) 5、懒汉式(线程安全,同步代码块) 6、双重检查 7、静态内部类 8、枚举 饿汉式(静态常量) 饿汉式(静态常量)实例对象构建步骤如下: 1、构造器私有化(防止new ); 2、类的内部创建对象; 3、向外暴露一个静态的公共方法。 代码实现: /** * <h1>饿汉式-静态常量</h1> */ public class HungryStaticVar { public static void main(String[] args) { Singleton instance1 = Singleton.getInstance(); Singleton instance2 = Singleton.getInstance(); System.out.println

聊聊高并发(二)结合实例说说线程封闭和背后的设计思想

心不动则不痛 提交于 2019-12-04 05:22:42
高并发问题抛去架构层面的问题,落实到代码层面就是多线程的问题。多线程的问题主要是线程安全的问题(其他还有活跃性问题,性能问题等)。 那什么是线程安全?下面这个定义来自《Java并发编程实战》,这本书强烈推荐,是几个Java语言的作者合写的,都是并发编程方面的大神。 线程安全指的是:当多个线程访问某个类时,这个类始终都能表现出正确的行为。 正确指的是“所见即所知”,程序执行的结果和你所预想的结果一致。 理解线程安全的概念很重要, 所谓线程安全问题,就是处理对象状态的问题 。如果要处理的对象是无状态的(不变性),或者可以避免多个线程共享的(线程封闭),那么我们可以放心,这个对象可能是线程安全的。当无法避免,必须要共享这个对象状态给多线程访问时,这时候才用到线程同步的一系列技术。 这个理解放大到架构层面,我们来设计业务层代码时,业务层最好做到无状态,这样就业务层就具备了可伸缩性,可以通过横向扩展平滑应对高并发。 所以我们处理线程安全可以有几个层次: 1. 能否做成无状态的不变对象。无状态是最安全的。 2. 能否线程封闭 3. 采用何种同步技术 我理解为能够“逃避”多线程问题,能逃则逃,实在不行了再来处理。 了解了线程封闭的背景,来说说线程封闭的具体技术和思路 1. 栈封闭 2. ThreadLocal 3. 程序控制线程封闭 栈封闭说白了就是多使用局部变量

Java中常用数据结构

情到浓时终转凉″ 提交于 2019-12-04 03:56:50
Java中常用数据结构 Collection list arrayList 底层数据结构是数组,查询快,增删慢,非线程安全 vector 线程安全版的arrayList linkedList 底层数据结构是链表,查询慢,增删快,非线程安全,有特有的功能addFirst及addLast,get和remove同理,可操作头尾的元素,因为其有序的特性,可以模拟栈和队列 set hashSet 底层数据结构是哈希表,基于HashMap实现,元素不可重复且无序 treeSet 底层数据结构是红黑树(自平衡二叉树),基于TreeMap实现,使用自然顺序排序,可通过创建set时使用Comparator进行排序 linkedHashSet 底层数据结构是链表加哈希表,由链表结构存储哈希表中的key,所以使得数据有序,同时具有hashSet唯一的特性 Map hashMap 键值对形式,键的数据结构是哈希表,保证了键的唯一性,排列无固定顺序 linkedHashMap 与hashMap相比,键的数据结构结合了链表,所以数据排列有序,这个顺序为数据插入顺序 treeMap 键的底层数据结构为红黑树,可保证键的自然排序,也可使用比较器Comparator进行特定方式排序 来源: CSDN 作者: JingbinChow 链接: https://blog.csdn.net/JingbinChow