HashSet源码分析

概览123public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable 值得注意的是HashSet底层是基于HashMap来实现的。HashSet是一个集合,集合是没有重复的元素的,不能保证顺序的。而且HashSet是非同步的。它的继承体系如下 属性1234private transient HashMap<E,Object> map;private static final Object PRESENT = new Object();

深入理解计算机系统读书笔记一

基础知识为什么计算机需要高速缓存?计算机程序是存储在磁盘中的。程序运行时,需要将程序加载到主存(内存条)中,但处理器处理程序时,又需要将指令从主存复制到处理器。程序的复制是开销。需要使用一种方式来使复制操作尽可能快的执行。根据机械原理,存储能力较大的设备的读写速度较慢。为了解决主存与处理器之间存在的读取数据的差距,就使用一种更小更快的存储设备,称为高数缓存存储器(cache memory)作为暂时集结的地方。 操作系统的两个基本功能1.防止硬件杯失控的应用程序滥用2.向应用程序提供简单一致的机制来控制复制而又通常不大相同的低级硬件设备。操作系统通过几个基本的抽象概念(进程、虚拟内存和文件)来实现这两个功能。

HashMap和Hashtable有什么不同?

类继承体系上的区别HashMap和Hashtable都实现了Map,Cloneable,Serializable接口。但两者不同的是HashMap继承的是AbstractMap而Hashtable继承的是Dictionary。Dictionary已经...

HashMap源码分析

概览12public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { 从继承关系上看好像并不没有什么特点。它基于哈希表实现了Map接口,并且允许null的值和null的键。HashMap并不能保证有序性。并且它不是同步的。 [] 属性分析1static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; 默认的初始容量为16.初始容量的大小和负载因子是非常影响其性能的两个参数。 1static final int MAXIMUM_CAPACITY = 1 << 30; 最大的允许的容量 1static final float DEFAULT_LOAD_FACTOR = 0.75f; 默认的负载因子(装填因子)。这是一个非常重要的参数。负载因子的定义为:填入表中的元素的个数/哈希表的长度(桶的个数)。所以装填因子越大产生冲突的可能性也越大。简单的来说就是装的越多其装满程度也越大,其装填因子也就越大。

LinkedList源码分析

概览123public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable 值得注意的时LinkedList除了实现了List还实现了Deque.也就是说LinkedList也可以当作队列来使用。LinkedList的底层是基于双向链表来实现的。所以它不支持随机访问,但也正是因为采用了双向链表实现,所以它有很高的插入和删除效率。 属性分析1transient int size = 0; size记录了链表中有效元素的个数。 12transient Node<E> first;transient Node<E> last; 双向链表的头指针和尾指针。这里有一个需要注意的地方,他们都使用了transient修饰,也就是说,他们不会被序列化。那么反序列化的时候怎么知道链表头和链表尾呢?其实在序列化的时候,只将链表本身和size进行了序列化,在反序列化的时候,首先获得size的值(此时firse和last为null),然后再将Node一个个读取出来,使用linkLast(E e)重构整个链表。而在这个方法中完成了first和last的赋值。

Vector源码分析

概览123public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable Vector和ArrayList非常的相似,两者都是基于数组实现的。两者最大的不同在于Vector是线程安全的。Vector为了确保线程安全,使用了大量的synchronized方法,这也使得Vector的性能较差。 属性解释1protected Object[] elementData; 和ArrayList类似,使用了数组来作为容器,但和ArrayList不同的是,它并没有transient 修饰,也就是说在序列化时,它也会被序列化。 1protected int elementCount; elementCount记录了Vector对象中存储的有效对象的数量。在创建Vector对象的时候如果没有指明大小的话,默认的大小为10. 1protected int capacityIncrement; capacityIncrement记录了每次扩容时增加的容量大小。如果在创建Vector对象时指定了capacityIncrement的大小,那么每次扩容增加的大小就为:capacityIncrement。如果在创建的时候,没有指定capacityIncrement的大小,那么每次扩容就会扩大两倍。这和ArrayList有些许的不同。

ArrayList源码分析

概览12public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable ArrayList是基于数组实现的,所以支持快速的随机访问。 属性解释1private static final int DEFAULT_CAPACITY = 10; 默认的初始容量。在创建ArrayList实例的时候可以不用指定其大小,默认的容量大小为10;但建议提前预估好合适的容量大小,因为扩容的开销比较大。后面会专门分析。 1private static final Object[] EMPTY_ELEMENTDATA = {}; 共享的空数组实例。在创建ArrayList对象实例的时候,如果容量大小指定为为0时,会让elementData引用共享的整个空数组。

java并发编程学习笔记二

编写正确的并发程序的关键在于共享对象、可变的状态进行访问管理 锁与可见性内置锁可以用来确保一个线程以某种可预见的方式看到另一个线程的影响。锁不仅仅是关于同步与互斥的,也是关于内存可见的。为了保证所有线程都能够看到共享的,可变变量的最新值,读取和写入线程必须使用公共的锁进行同步。 1234567891011@ThreadSafepublic class SynchronziedInteger{ private int value; public synchronized int get(){ return value; } public synchronized void set(int value){ this.value=value; }} 最低限安全性当一个线程在没有同步的情况下读取变量,它可能会得到一个过期值。但它至少可以看到某个线程在那里设定的一个真实数值,而不是一个凭空而来的值。这样的保证称为最低限的安全性。 volatile 变量它可以确保对一个变量的更新以可预见的方式告知其它的线程。当一个域被声明为volatile类型后,编译器运行时会监视这个变量,它是共享的,而且对它的操作不会与其它内存操作一起被重排序。volatile变量不会缓存在寄存器或者缓存在对其它处理器隐藏的地方。所以读一个volatile变量时,总会返回某一线程所写入的最新值。 当一个共享变量声明为volatile后:1.当写一个volatile变量时,JMM会把该线程对应的本地内存种的变量强制刷新到主内存中去。2.这个写操作会导致其它线程中的缓存无效。3.volatile会禁止语义重排序。

java synchronized关键字

在java编程中,当可能存在多个线程同时访问一部分资源时,可能会出现一些访问冲突。为了解决冲突,java提供了synchronized关键值,通过加锁的方式,保证访问的有序性。 synchronized关键字的两种作用范围1.作用于对象. 12345678910public synchronized void method(){ //}等价写法public void method(){ synchronized(this){ ... }} 作用于对象可以防止多个线程同时访问该对象的sychronized方法。所以不同实例时不干扰的,也就是说,以该类创建的其它对象依然可以同时访问该sychronized方法。 2.作用于类 1234567891011public static synchronized void method(){ }等价写法:public void method(){ synchronized(Myclass.class){ ... }} 作用于类可以防止多个线程同时访问该类的实例的synchronized方法。所以该类的实例之间时存在干扰的。也就是说,该类创建的对象不能同时访问该synchronized方法了。

Java static关键字的几种用法

static关键字的几种用法 修饰成员变量,和方法 修饰内部类 修饰代码块 静态导包 修饰成员变量和方法static修饰的成员变量或方法属于类,不属于对象。所有该类的实例都共享一个变量或方法。放在内存的方法区 123456789101112131415161718192021public class JavaStatic { /** * 静态成员变量 */ private static int age; /** * 静态方法 */ private static void printName(){ System.out.println("Name"); } public static void main(String[] args) { /*静态成员变量或方法直接使用类名进行调用*/ System.out.println(JavaStatic.age); JavaStatic.printName(); }}

11112131415