线程安全

单例模式

扶醉桌前 提交于 2019-11-30 10:34:33
介绍 类的单例设计模式,就是采取一定的方法来保证在整个软件系统中,某个类只存在一个对象实例。且该类只提供一个取得其对象实例的方法(静态方法)。 八种方式 单例模式有八种方式: 饿汉式(静态常量) 饿汉式(静态代码块) 懒汉式(线程不安全) 懒汉式(线程安全,同步方法) 懒汉式(线程安全,同步代码块) 双重检查 静态内部类 枚举 步骤 步骤大致如下: 构造器私有化(防止外部new) 类的内部创建对象 向外提供一个静态公共方法(getInstance) 饿汉式(静态常量) 代码: package singleton.type1; public class Singleton { private Singleton() { } private static final Singleton instance = new Singleton(); public static Singleton getInstance() { return instance; } } 测试代码: package singleton.type1; public class SingletonTest { public static void main(String[] args) { Singleton instance = Singleton.getInstance(); Singleton

谈谈线程安全

眉间皱痕 提交于 2019-11-30 10:26:53
进程之间有独立的内存空间,相互之间访问不到。 但是进程中有多个线程。每个线程都有各自的栈内存,这个栈内存也是各个线程自己私有的,别人访问不到; 但是进程中有公共的 堆空间 ,是多个线程都可以访问得到的空间。如果大家都能访问到这个空间中的某个对象或方法。 那就存在数据被意外修改的风险,使得某个线程的数据被污染。这就是线程安全问题。 非线程安全 是指多线程操作同一个对象可能会出现问题。而 线程安全 则是多线程操作同一个对象不会有问题。 为例保证线程安全,于是就有了一些机制: 例如CAS(compare and swap),保存数据的状态然后检查数据是否被修改了,被修改的话,就重头再来。->开销较大,适用于线程不多,数据被修改的概率不大,但是存在这种可能; 还有一种是加锁机制->也是有开销的,但是能保证数据不被修改,适用于线程较多,大概率数据会被修改的情况; 线程安全必须要使用很多synchronized关键字来同步控制,所以必然会导致性能的降低。 所以在使用的时候,如果是多个线程操作同一个对象,那么使用线程安全的Vector;否则,就使用效率更高的ArrayList。 非线程安全!=不安全 ==================================================== 相关链接: 线程安全这么回答才牛逼: https://www.cnblogs.com

java面试(1)

◇◆丶佛笑我妖孽 提交于 2019-11-30 10:13:56
Java集合详解【面试+工作】 在说集合前我们不得不说一下 数组 数组的作用: 存放一组相同的数据类型(基本或对象)的数据,从而实现对数据的管理 优势: 可以快速的通过下标对数组元素进行访问,效率高 劣势: 容量实现定义好了,不能随着需求变化而扩容 因此出现了更好的集合框架 一、数组和集合的比较 数组不是面向对象的,存在明显的缺陷,集合弥补了数组的缺点,比数组更灵活更实用,而且不同的集合框架类可适用不同场合。如下: 1:数组能存放基本数据类型和对象,而集合类存放的都是对象的引用,而非对象本身! 2:数组容易固定无法动态改变,集合类容量动态改变。 3:数组无法判断其中实际存有多少元素,length只告诉了数组的容量,而集合的size()可以确切知道元素的个数 4:集合有多种实现方式和不同适用场合,不像数组仅采用顺序表方式 5:集合以类的形式存在,具有封装、继承、多态等类的特性,通过简单的方法和属性即可实现各种复杂操作,大大提高了软件的开发效率 二、Java集合 Collection和Map,是集合框架的根接口。 Collection的子接口: Set:接口 ---实现类: HashSet、LinkedHashSet Set的子接口SortedSet接口---实现类:TreeSet List:接口---实现类: LinkedList,Vector,ArrayList List集合

Java 8 时间日期库的20个使用示例

主宰稳场 提交于 2019-11-30 09:23:45
在本篇教程中我们将通过几个简单的任务示例来学习如何使用Java 8的这套API。Java对日期,日历及时间的处理一直以来都饱受诟病,尤其是它决定将java.util.Date定义为可修改的以及将SimpleDateFormat实现成非线程安全的。看来Java已经意识到需要为时间及日期功能提供更好的支持了,这对已经习惯使用Joda时间日期库的社区而言也是件好事。关于这个新的时间日期库的最大的优点就在于它定义清楚了时间日期相关的一些概念,比方说,瞬时时间(Instant),持续时间(duration),日期(date),时间(time),时区(time-zone)以及时间段(Period)。同时它也借鉴了Joda库的一些优点,比如将人和机器对时间日期的理解区分开的。Java 8仍然延用了ISO的日历体系,并且与它的前辈们不同,java.time包中的类是不可变且线程安全的。新的时间及日期API位于java.time包中,下面是里面的一些关键的类: Instant——它代表的是时间戳 LocalDate——不包含具体时间的日期,比如2014-01-14。它可以用来存储生日,周年纪念日,入职日期等。 LocalTime——它代表的是不含日期的时间 LocalDateTime——它包含了日期及时间,不过还是没有偏移信息或者说时区。 ZonedDateTime—

java.util.concurrent.atomic随笔及volatile语义

≡放荡痞女 提交于 2019-11-30 08:20:40
一个原子操作( atomic operation )是个不能分割的整体,没有其它线程( thread )能够中断或检查正在原子操作中的变量。一个原子( atomic )类型就是一个原子操作可用的类型,它可以在基本上没有锁( lock )的情况下做到线程安全( thread-safe )。 java .util.concurrent.atomic 包就是提供原子操作的类的小工具包,支持在单个变量上解除锁定的线程安全编程。包中的类将 volatile 值、字段和数组元素的概念扩展到那写也支持原子条件更新操作的类。如 AtomicReference ,一个“可以用原子方式更新的对象引用”。 JDK 的文档中说:“ 设计原子类主要用作各种块,用于实现非阻塞数据结构和相关基础结构类 。 compareAndSet() 方法不是锁定的常规替换方法。仅当对象的重要更新限于单个变量时才应用它” 类图解: ?从类图中可以清晰的得出:这些基本都是实现 java 常用的基本类型及他们的数组的原子实现。 volatile语义 volatile相当于synchronized的弱实现,也就是说volatile实现了类似synchronized的语义,却又没有锁机制。它确保对volatile字段的更新以可预见的方式告知其他的线程。 volatile包含以下语义: (1) Java

Java学习资料-StringBuilder与StringBuffer的区别

荒凉一梦 提交于 2019-11-30 07:11:42
相信大家看到过很多比较String和StringBuffer区别的文章,也明白这两者的区别,然而自从Java 5.0发布以后,我们的比较列表上将多出一个对象了,这就是StringBuilder类。String类是不可变类,任何对String的改变都会引发新的String对象的生成;而StringBuffer则是可变类,任何对它所指代的字符串的改变都不会产生新的对象,可变和不可变类这一对对象已经齐全了,那么为什么还要引入新的StringBuilder类干吗?相信大家都有此疑问,我也如此。下面,我们就来看看引入该类的原因。 为什么会出现那么多比较String和StringBuffer的文章? 原因在于当改变字符串内容时,采用StringBuffer能获得更好的性能。既然是为了获得更好的性能,那么采用StringBuffer能够获得最好的性能吗? 答案是NO! 为什么? 如果你读过《Think in Java》,而且对里面描述HashTable和HashMap区别的那部分章节比较熟悉的话,你一定也明白了原因所在。对,就是支持线程同步保证线程安全而导致性能下降的问题。HashTable是线程安全的,很多方法都是synchronized方法,而HashMap不是线程安全的,但其在单线程程序中的性能比HashTable要高。StringBuffer和StringBuilder类的区别也在于此

单例设计模式八种写法

安稳与你 提交于 2019-11-30 06:34:30
所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类 只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。 比如Hibernate的SessionFactory,它充当数据存储源的代理,并负责创建Session 对象。SessionFactory并不是轻量级的,一般情况下,一个项目通常只需要一个 SessionFactory就够,这是就会使用到单例模式 1.饿汉式(静态常量) 饿汉式(静态常量)应用实例 步骤如下: 构造器私有化 (防止 new ) 类的内部创建对象 向外暴露一个静态的公共方法。getInstance 代码实现 public class SingletonTest01 { public static void main(String[] args) { //测试 Singleton instance = Singleton.getInstance(); Singleton instance2 = Singleton.getInstance(); System.out.println(instance == instance2); // true System.out.println("instance.hashCode=" + instance.hashCode()); System.out.println(

面试(四)

痞子三分冷 提交于 2019-11-30 06:34:03
Java中如何获取到线程dump文件 死循环、死锁、阻塞、页面打开慢等问题,打线程dump是最好的解决问题的途径。所谓线程dump也就是线程堆栈,获取到线程堆栈有两步: (1)获取到线程的pid,可以通过使用jps命令,在Linux环境下还可以使用ps -ef | grep java (2)打印线程堆栈,可以通过使用jstack pid命令,在Linux环境下还可以使用kill -3 pid 如何在两个线程之间共享数据 通过在线程之间共享对象就可以了,然后通过wait/notify/notifyAll、await/signal/signalAll进行唤起和等待,比方说阻塞队列BlockingQueue就是为线程之间共享数据而设计的 sleep方法和wait方法有什么区别 sleep方法和wait方法都可以用来放弃CPU一定的时间,不同点在于如果线程持有某个对象的监视器,sleep方法不会放弃这个对象的监视器,wait方法会放弃这个对象的监视器 为什么wait()方法和notify()/notifyAll()方法要在同步块中被调用 这是JDK强制的,wait()方法和notify()/notifyAll()方法在调用前都必须先获得对象的锁 wait()方法和notify()/notifyAll()方法在放弃对象监视器时有什么区别 区别在于: wait()方法立即释放对象监视器

ConcurrentLinkedQueue和LinkedBlockingQueue比较

房东的猫 提交于 2019-11-30 06:24:45
1、阻塞和非阻塞 ConcurrentLinkedQueue是非阻塞的线程安全队列 2、ConcurrentLinkedQueue是无界的 LinkedBlockingQueue可以指定大小 3、加锁方式 ConcurrentLinkedQueue使用CAS 原子指令来保证线程安全。吞吐量更高 LinkedBlockingQueue 使用ReentrantLock方式加锁 4、使用场景 LinkedBlockingQueue通常用于生产消费模型,有阻塞的场景。 其他非场景如何线程不想阻塞 可考虑ConcurrentLinkedQueue 4、ConcurrentLinkedQueue不一致性 ConcurrentLinkedQueue的head tail并非总是指向队列头尾元素,可能处于不一致状态 来源: https://www.cnblogs.com/yangfei629/p/11567988.html

高并发下的Java数据结构(List、Set、Map、Queue)

隐身守侯 提交于 2019-11-30 06:10:00
1.并发List Vector 或者 CopyOnWriteArrayList 是两个线程安全的List实现,ArrayList 不是线程安全的。因此,应该尽量避免在多线程环境中使用ArrayList。如果因为某些原因必须使用的,则需要使用 Collections.synchronizedList(List list) 进行包装。 示例代码: List list = Collections.synchronizedList(new ArrayList()); ...synchronized (list) { Iterator i = list.iterator(); // 必须在同步块中 while (i.hasNext()) foo(i.next());} 遍历的操作需要自己加锁,而add之类的方法则不需要,自己看一下源码就理解了 CopyOnWriteArrayList 的内部实现与Vector又有所不同。顾名思义,Copy-On-Write 就是 CopyOnWriteArrayList 的实现机制。即当对象进行写操作时,复制该对象;若进行的读操作,则直接返回结果,操作过程中不需要进行同步。 CopyOnWriteArrayList 很好地利用了对象的不变性,在没有对对象进行写操作前,由于对象未发生改变,因此不需要加锁。而在试图改变对象时,总是先获取对象的一个副本