线程安全

String不变性以及String/StringBuffer/StringBuilder的区别

蹲街弑〆低调 提交于 2020-02-17 06:36:39
String/StringBuffer/StringBuilder的区别 String、StringBuffer、StringBuilder都是final 类, 都不允许被继承 String 长度是不可变的, StringBuffer、StringBuilder 长度是可变的 StringBuffer 是线程安全的, StringBuilder 不是线程安全的,但它们两个中的所有方法都是相同的,StringBuffer在StringBuilder的方法之上添加了synchronized修饰,保证线程安全 StringBuilder比StringBuffer拥有更好的性能。因为它支持StringBuffer的所有操作,但是因为它不执行同步,不会有线程安全带来额外的系统消耗,所以速度更快 如果一个String类型的字符串,在编译时就可以确定是一个字符串常量,则编译完成之后,字符串会自动拼接成一个常量。此时String的速度比StringBuffer和StringBuilder的性能好的多 可变性   String 类中使用 final 关键字修饰字符数组来保存字符串,private final char value[],因此String 对象是不可变的。而StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在

C# Lazy Loading

二次信任 提交于 2020-02-16 00:12:08
C# Lazy Loading 前言 按需加载对象延迟加载实际是推迟进行创建对象,直到对其调用后才进行创建初始化,延迟(懒加载)的好处是提高系统性能,避免不必要的计算以及不必要的资源浪费。 常规有这些情况: 对象创建成本高且程序可能不会使用它。 例如,假定内存中有具有 Orders 属性的 Customer 对象,该对象包含大量 Order 对象,初始化这些对象需要数据库连接。 如果用户永远不要求显示 Orders 或在计算中使用该数据,则无需使用系统内存或计算周期来创建它。 通过使用 Lazy 来声明 Orders对象用于迟缓初始化,可以避免在不使用该对象时浪费系统资源。 对象创建成本高,且希望将其创建推迟到其他高成本操作完成后。 例如,假定程序在启动时加载多个对象实例,但是只需立即加载其中一部分。 可以通过推迟初始化不需要的对象,直到创建所需对象,提升程序的启动性能。(来源官方) 示例 创建用户类 public class User { public string Name { get; set; } public int Age { get; set; } public User() { this.Name = "Name"; this.Age = 0; } } 默认情况下,Lazy 对象是线程安全的。 也就是说,如果构造函数没有指定线程安全性的类型,该函数创建的 Lazy

如何设计一个本地缓存,涨姿势了!

不问归期 提交于 2020-02-15 16:22:06
作者: ksfzhaohui; https://my.oschina.net/OutOfMemory/blog/3133013 最近在看Mybatis的源码,刚好看到缓存这一块,Mybatis提供了一级缓存和二级缓存;一级缓存相对来说比较简单,功能比较齐全的是二级缓存,基本上满足了一个缓存该有的功能。 当然如果拿来和专门的缓存框架如ehcache来对比可能稍有差距,本文我们将来整理一下实现一个本地缓存都应该需要考虑哪些东西。 考虑点 考虑点主要在数据用何种方式存储,能存储多少数据,多余的数据如何处理等几个点,下面我们来详细的介绍每个考虑点,以及该如何去实现; 1.数据结构 首要考虑的就是数据该如何存储,用什么数据结构存储,最简单的就直接用Map来存储数据;或者复杂的如redis一样提供了多种数据类型哈希,列表,集合,有序集合等,底层使用了双端链表,压缩列表,集合,跳跃表等数据结构; 2.对象上限 因为是本地缓存,内存有上限,所以一般都会指定缓存对象的数量比如1024,当达到某个上限后需要有某种策略去删除多余的数据; 3.清除策略 上面说到当达到对象上限之后需要有清除策略,常见的比如有LRU(最近最少使用)、FIFO(先进先出)、LFU(最近最不常用)、SOFT(软引用)、WEAK(弱引用)等策略; 4.过期时间 除了使用清除策略,一般本地缓存也会有一个过期时间设置

线程,线程安全与python的GIL锁

别来无恙 提交于 2020-02-15 06:55:56
  今天看到一篇文章,讲述的是几个提升python性能的项目: 传送门   在看的过程中,接触到一个名词,一个从学python开始就一直看到,但是从来都是一知半解的名词,心里不开心,必须把它搞明白,对了,这个词就是 GIL。网上搜索了一些资料,粗浅的理解了什么是GIL,自己感觉学习的过程比较好,感觉略有收获,老规矩,为了巩固知识,自己整片文章出来写一写,其实好多文章已经写的很完善了,所以这篇随笔,只做知识巩固,如有雷同,请各位原创作者原谅,小菜鸟一枚,如果哪里写的有问题,还请各位前辈不吝指正。   一句话: 解决多线程之间数据完整性和状态同步的最简单方法自然就是加锁。   首先,GIL的全名, Global Interpreter Lock ,鉴于英文水平,不做名词翻译,以免误导。大体解释一下,这个锁就是用来为了解决Cpython多线程中线程不安全问题引入的一个全局排它锁,它的作用就是在多线程情况下,保护共享资源,为了不让多个线程同时操作共享资源,导致不可预期的结果而加上的锁,在一个线程操作共享资源时,其他线程请求该资源,只能等待GIL解锁。这个设置在Cpython刚引入多线程概念的时候就有了,然后后续的各种包和组件开发都不可避免的受到了GIL的影响,所以有人会说,python在多线程处理的时候很慢。python GIL实现方式类似于如下伪代码: if __name__ == '_

Java集合常见面试题

江枫思渺然 提交于 2020-02-12 02:36:28
适可而止,见好就收 来源主要是 牛客 的Java实习面经。下面的回答直接背就可以,需要一定的Java基础,适合春招实习的同学,但是我会在每个问题下把有助于理解的博客贴出来。如果发现有问题欢迎私聊我或留言我会在下面更新 Map 1. Map的底层结构 腾讯19年秋招 这个题乍一看没有什么思路(因为Map是个集合,当然也有可能是我记错了),所以我们可以先介绍一下Map然后转到HashMap中 Map是一种使用键值对存储的集合。Map会维护与Key有关联的值。两个Key可以引用相同的对象,但Key不能重复,典型的Key是String类型,但也可以是任何对象。 在整个Map系列中,AbstractMap抽象类实现了Map,SortedMap接口继承了Map。而我们常用的HashMap,HashTable,TreeMap和ConcurrentHashMap有继承了AbstractMap类。 其中,HashTable和ConcurrentHashMap是线程安全的。前者是通过synchronized实现的,后者是通过AQS实现的。其中要注意HashTable不能存空值,HashMap是线程不安全的,key可以为空。TreeMap通过二叉树算法实现有序集合,它实现了SortedMap接口 2. HashMap的原理 阿里17年实习,小米19年秋招本科,滴滴19年秋招本科,网易19年秋招本科

HashMap、HashTable、ConcurrentHashMap的区别

我的未来我决定 提交于 2020-02-11 14:18:55
一、相关概念 1、Map的概念 javadoc中对Map的解释如下: An objectthat maps keys to values . Amap cannot contain duplicatekeys; each key can map to at most one value. This interface takes the place of the Dictionary class, which was atotally abstract class rather than an interface. The Map interface provides three collection views, which allow amap's contents to be viewed as a set of keys, collection of values,or set of key-value mappings. 从上可知,Map用于存储“key-value”元素对,它将一个key映射到一个而且只能是唯一的一个value。 Map可以使用多种实现方式,HashMap的实现采用的是hash表;而TreeMap采用的是红黑树。 2、HashMap 实现了Map接口,实现了将唯一键隐射到特定值上。 允许一个NULL键和多个NULL值。非线程安全。 3、HashTable

Java回顾--集合

回眸只為那壹抹淺笑 提交于 2020-02-11 14:15:41
1、Collection接口和Collections包装类:    Collection概念: 是一个集合接口,提供了对集合对象进行基本操作的通用接口方法。   有以下结构:     |--List     |  |--LinkedList     |  |--ArrayList     |  |--Vector     |    |--stack     |--Set    Collections: 包含各种有关集合操作的静态多态方法,且该类无法实例化,相当于一个工具类。 2、HashMap、HashTable和ConcurrentHashMap:    HashMap的特点 :线程不安全,允许传入 null值,不能保存映射的顺序。由数组(默认长度为16)+链表组成,jdk1.8后,若其链表长度大于8,就会转变成红黑树。     ps:HashMap线程不安全,是因为多个对象同时对同一HashMap进行操作时,会导致脏读、数据丢失的发生。   详细参考:https://www.cnblogs.com/aspirant/p/8908399.html    HashTable: 可以理解为线程安全的HashMap,为什么是线程安全的,因为它的put、remove、get方法都被synchronized修饰,使其同步,自然是线程安全的了。    ConcurrentHashMap:

单例模式

人走茶凉 提交于 2020-02-11 12:55:21
定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。    Singleton:负责创建Singleton类自己的唯一实例,并提供一个getInstance的方法,让外部来访问这个类的唯一实例。 分类:   懒汉式(时间换空间):不加同步时线程不安全     1.线程不安全 public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }     2.线程安全(加锁,效率慢) public class Singleton { private static Singleton instance; private Singleton (){} public static synchronized Singleton getInstance() {   if (instance == null) {   instance = new Singleton();    }   return instance; } }     3.双重加锁机制    

2020 Java面试题最新(五锁机制)

无人久伴 提交于 2020-02-10 17:44:28
锁的原因都是由并发问题发生的,在此我只是写一些面试中可能会问到的问题以及问题的答案,并不是给大家深入的讲解锁机制 一般面试官问都是从一个点引入一个点的问问题,所以我就先从线程问题引入到锁问题 1.说说线程安全问题 线程安全是多线程领域的问题,线程安全可以简单理解为一个方法或者一个实例可以在多线程环境中使用而不会出现问题 在 Java 多线程编程当中,提供了多种实现 Java 线程安全的方式: 最简单的方式,使用 Synchronization 关键字 使用 java.util.concurrent.atomic 包中的原子类,例如 AtomicInteger 使用 java.util.concurrent.locks 包中的锁 使用线程安全的集合 ConcurrentHashMap 使用 volatile 关键字,保证变量可见性(直接从内存读,而不是从线程 cache 读) 2.volatile 实现原理 在 JVM 底层 volatile 是采用“内存屏障”来实现的 缓存一致性协议(MESI协议)它确保每个缓存中使用的共享变量的副本是一致的。其核心思想如下:当某个 CPU 在写数据时,如果发现操作的变量是共享变量,则会通知其他 CPU 告知该变量的缓存行是无效的,因此其他 CPU 在读取该变量时,发现其无效会重新从主存中加载数据 3.synchronize 实现原理

详解volatile在C++中的作用

泄露秘密 提交于 2020-02-10 07:41:04
volatile的介绍 volatile类似于大家所熟知的const也是一个类型修饰符。volatile是给编译器的指示来说明对它所修饰的对象不应该执行优化。volatile的作用就是用来进行多线程编程。在单线程中那就是只能起到限制编译器优化的作用。所以单线程的童鞋们就不用浪费精力看下面的了。 没有volatile的结果 如果没有volatile,你将无法在多线程中并行使用到基本变量。下面举一个我开发项目的实例(这个实例采用的是C#语言但不妨碍我们讨论C++)。在学校的一个.Net项目的开发中,我曾经在多线程监控中用到过一个基本变量Int32型的,我用它来控制多线程中监控的一个条件。考虑到基本变量是编译器自带的而且无法用lock锁上,我想当然的以为是原子操作不会有多线程的问题,可实际运行后发现程序的运行有时正常有时异常,改为用Dictionary对象处理并加锁以后才彻底正常。现在想来应该是多线程同时操作该变量了,具体的将在下面说清。 volatile的作用 如果一个基本变量被volatile修饰,编译器将不会把它保存到寄存器中,而是每一次都去访问内存中实际保存该变量的位置上。这一点就避免了没有volatile修饰的变量在多线程的读写中所产生的由于编译器优化所导致的灾难性问题。所以多线程中必须要共享的基本变量一定要加上volatile修饰符。当然了