synchronized

JMM和Volatile底层原理分析

雨燕双飞 提交于 2019-12-16 10:49:54
JMM和volatile分析 1.JMM:Java Memory Model,java线程内存模型 JMM:它是一个抽象的概念,描述的是线程和内存间的通信,java线程内存模型和CPU缓存模型类似,它是标准化的, 用于屏蔽硬件和操作系统对内存访问的差异性 。 2.JMM和8大原子操作结合 3.volatile的应用及底层原理探究 volatile : 轻量级的synchronized,在多处理器的开发中保证了共享变量的"可见性"。可见性的意思:当一个线程修改了某个共享变量时,其他使用到该共享变量的线程能够及时读取到修改的值。修饰得当,比synchronized的执行成本更低,因为它不会引起线程上下文切换和调度。 public class VolatileTest { private static volatile boolean flag = false; public static void main(String[] args) { update(); } public static void update(){ flag = true; System.out.println(flag); } } Volatile JIT编译器编译java代码为汇编指令查看 1.在jdk\jre\bin\ 目录下添加 hsdis-amd64.lib 2.在jdk1.8\jre\bin

HashMap,HashSet,HashTable的区别

这一生的挚爱 提交于 2019-12-16 03:33:49
什么是HashMap HashMap实现了Map接口,Map接口对键值对进行映射。Map中不允许重复的键。Map接口有两个基本的实现,HashMap和TreeMap。TreeMap保存了对象的排列次序,而HashMap则不能。HashMap允许键和值为null。HashMap是非synchronized的,但collection框架提供方法能保证HashMap synchronized,这样多个线程同时访问HashMap时,能保证只有一个线程更改Map。 public Object put(Object Key,Object value)方法用来将元素添加到map中。 什么是HashSet HashSet实现了Set接口,它不允许集合中有重复的值,当我们提到HashSet时,第一件事情就是在将对象存储在HashSet之前,要先确保对象重写equals()和hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有储存相等的对象。如果我们没有重写这两个方法,将会使用这个方法的默认实现。 public boolean add(Object o)方法用来在Set中添加元素,当元素值重复时则会立即返回false,如果成功添加的话会返回true。 什么是Hashtable 哈希表(Hashtable)又称为“散置”,Hashtable是会根据索引键的哈希程序代码组织成的索引键

Synchronized原理分析

社会主义新天地 提交于 2019-12-16 00:13:20
文章简介 synchronized想必大家都不陌生,用来解决线程安全问题的利器。同时也是Java高级程序员面试比较常见的面试题。这篇文正会带大家彻底了解synchronized的实现。 内容导航 什么时候需要用Synchronized synchronized的使用 synchronized的实现原理分析 什么时候需要用Synchronized 想必大家对synchronized都不陌生,主要作用是在多个线程操作共享数据的时候,保证对共享数据访问的线程安全性。 比如在下面这个图片中,两个线程对于i这个共享变量同时做i++递增操作,那么这个时候对于i这个值来说就存在一个不确定性,也就是说理论上i的值应该是2,但是也可能是1。而导致这个问题的原因是线程并行执行i++操作并不是原子的,存在线程安全问题。所以通常来说解决办法是通过加锁来实现线程的串行执行,而synchronized就是java中锁的实现的关键字。 synchronized在并发编程中是一个非常重要的角色,在JDK1.6之前,它是一个重量级锁的角色,但是在JDK1.6之后对synchronized做了优化,优化以后性能有了较大的提升(这块会在后面做详细的分析)。 先来看一下synchronized的使用 Synchronized的使用 synchronized有三种使用方法,这三种使用方法分别对应三种不同的作用域,代码如下

synchronized关键字

断了今生、忘了曾经 提交于 2019-12-15 22:50:09
synchronized关键字 一、语义 1、当线程释放锁时,JMM会把本地内存中的数据刷新到主内存中。 2、当获取锁时,会把本地内存设置为无效,从主内存中读取数据。 二、synchronized对象 对于synchronized的同步,锁是java中的对象。 1、对于实例方法,锁是当前对象的实例。 2、对于静态方法,锁是该类的Class对象。 3、对于同步代码块,锁是synchronized后面跟的对象。 JVM基于进入和退出monitor对象来实现synchronized代码块的。代码块同步是使用monitorenter 和monitorexit指令实现的。在java中,每一个对象都与一个minitor相对应。当且一个monitor被持有后,它处于锁定状态。线程执行到monitorenter指令时,将会尝试获取对象所对应的monitor的所有权,即尝试获得对象的锁。 三、JAVA对象头 1、如果java对象是一个数组,那么java对象头用三个字来表示 2、如果java对象不是数组,那么用两个字来表示 在32位虚拟机中,一个字长位32位。64位虚拟机中,一个字长是64位。 在java对象头中,第一个字为markword,默认存储对象的分代年龄,hashcode和锁标志位。其中的数据并会随着锁标志位的变化而变化。 第二个字即为CLass Metadata Address

美团 Java 面试 154 道题分享

和自甴很熟 提交于 2019-12-14 13:39:32
Java集合22题 ArrayList 和 Vector 的区别。 说说 ArrayList,Vector, LinkedList 的存储性能和特性。 快速失败 (fail-fast) 和安全失败 (fail-safe) 的区别是什么? hashmap 的数据结构。 HashMap 的工作原理是什么? Hashmap 什么时候进行扩容呢? List、Map、Set 三个接口,存取元素时,各有什么特点? Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用 == 还是 equals()? 它们有何区别? 两个对象值相同 (x.equals(y) == true),但却可有不同的 hash code,这句话对不对? heap 和 stack 有什么区别。 Java 集合类框架的基本接口有哪些? HashSet 和 TreeSet 有什么区别? HashSet 的底层实现是什么? LinkedHashMap 的实现原理? 为什么集合类没有实现 Cloneable 和 Serializable 接口? 什么是迭代器 (Iterator)? Iterator 和 ListIterator 的区别是什么? 数组 (Array) 和列表 (ArrayList) 有什么区别?什么时候应该使用 Array 而不是 ArrayList? Java 集合类框架的最佳实践有哪些? Set

JAVA并发编程:LOCK(锁)

元气小坏坏 提交于 2019-12-14 01:37:58
一.synchronized的缺陷   synchronized是java中的一个关键字,也就是说是Java语言内置的特性。那么为什么会出现Lock呢?   在上面一篇文章中,我们了解到如果一个代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况:   1)获取锁的线程执行完了该代码块,然后线程释放对锁的占有;   2)线程执行发生异常,此时JVM会让线程自动释放锁。   那么如果这个获取锁的线程由于要等待IO或者其他原因(比如调用sleep方法)被阻塞了,但是又没有释放锁,其他线程便只能干巴巴地等待,试想一下,这多么影响程序执行效率。   因此就需要有一种机制可以不让等待的线程一直无期限地等待下去(比如只等待一定的时间或者能够响应中断),通过Lock就可以办到。   再举个例子:当有多个线程读写文件时,读操作和写操作会发生冲突现象,写操作和写操作会发生冲突现象,但是读操作和读操作不会发生冲突现象。   但是采用synchronized关键字来实现同步的话,就会导致一个问题:   如果多个线程都只是进行读操作,所以当一个线程在进行读操作时,其他线程只能等待无法进行读操作。   因此就需要一种机制来使得多个线程都只是进行读操作时,线程之间不会发生冲突

Is this variable being safely accessed by using synchronization?

*爱你&永不变心* 提交于 2019-12-13 22:41:50
问题 I have a case in which a Java class has a superclass that contains a synchronized block. Class SuperClassA { private Bitmap bmpA; protected abstract Bitmap createBitmap(); public void run() { synchronized (this) { bmpA = createBitmap(); } } // some other codes. } Class SubClassB extends SuperClassA { private Bitmap outBmpB; protected Bitmap createBitmap() { outBmpB = ..... // create and process "outBmpB". Bitmap bmp; bmp = ..... // create and process "bmp". return bmp; } public Bitmap

你说的曾经没有我的故事 提交于 2019-12-13 21:32:15
使用synchronized获取互斥锁的几点说明 原文链接:https://blog.csdn.net/ns_code/article/details/17199201 采用synchronized修饰符实现的同步机制叫做互斥锁机制,它所获得的锁叫做互斥锁。每个对象都有一个monitor(锁标记),当线程拥有这个锁标记时才能访问这个资源,没有锁标记便进入锁池。任何一个对象系统都会为其创建一个互斥锁,这个锁是为了分配给线程的,防止打断原子操作。每个对象的锁只能分配给一个线程,因此叫做互斥锁。 1、如果同一个方法内同时有两个或更多线程,则每个线程有自己的局部变量拷贝。 2、类的每个实例都有自己的对象级别锁。当一个线程访问实例对象中的synchronized同步代码块或同步方法时,该线程便获取了该实例的对象级别锁,其他线程这时如果要访问synchronized同步代码块或同步方法,便需要阻塞等待,直到前面的线程从同步代码块或方法中退出,释放掉了该对象级别锁。 3、访问同一个类的不同实例对象中的同步代码块,不存在阻塞等待获取对象锁的问题,因为它们获取的是各自实例的对象级别锁,相互之间没有影响。 4、持有一个对象级别锁不会阻止该线程被交换出来,也不会阻塞其他线程访问同一示例对象中的非synchronized代码。当一个线程A持有一个对象级别锁

悲观锁和乐观锁

拜拜、爱过 提交于 2019-12-13 21:17:03
何谓悲观锁与乐观锁 乐观锁对应于生活中乐观的人总是想着事情往好的方向发展,悲观锁对应于生活中悲观的人总是想着事情往坏的方向发展。这两种人各有优缺点,不能不以场景而定说一种人好于另外一种人。 悲观锁 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。 乐观锁 总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。 两种锁的使用场景 从上面对两种锁的介绍,我们知道两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下(多读场景),即冲突真的很少发生的时候

Will value objects in a copy of a static ConcurrentHashMap reference the same value objects as the original?

落爺英雄遲暮 提交于 2019-12-13 20:09:14
问题 I have a two part question. I have: private static ConcurrentHashMap<Integer, Servers> servers= null; which I later populate. In method getAllServers , I'm doing this: public static synchronized ConcurrentHashMap<Integer, Server> getAllServers() { ConcurrentHashMap<Integer, Server> toReturn = new ConcurrentHashMap<>(); for(Integer i = 0; i < servers.size(); i ++ ) { Server s = servers.get(i); if(s.isAlive()) { s.incrementConns(); toReturn.put(i, s); } } return toReturn; } Q: Will