The execution of any one of the Java Virtual Machine instructions new, getstatic, putstatic, or invokestatic that references C (§new, §getstatic, §putstatic, §invokestatic). These instructions reference a class or interface directly or indirectly through either a field reference or a method reference.
Upon execution of a new instruction, the referenced class is initialized if it has not been initialized already.
Upon execution of a getstatic, putstatic, or invokestatic instruction, the class or interface that declared the resolved field or method is initialized if it has not been initialized already.
The first invocation of a java.lang.invoke.MethodHandle instance which was the result of method handle resolution (§5.4.3.5) for a method handle of kind 2 (REF_getStatic), 4 (REF_putStatic), 6 (REF_invokeStatic), or 8 (REF_newInvokeSpecial).
This implies that the class of a bootstrap method is initialized when the bootstrap method is invoked for an invokedynamic instruction (§invokedynamic), as part of the continuing resolution of the call site specifier.
Invocation of certain reflective methods in the class library (§2.12), for example, in class Class or in package java.lang.reflect.
If C is a class, the initialization of one of its subclasses.
If C is an interface that declares a non-abstract, non-static method, the initialization of a class that implements C directly or indirectly.
If C is a class, its designation as the initial class at Java Virtual Machine startup (§5.2).
/** * The table, initialized on first use, and resized as * necessary. When allocated, length is always a power of two. * (We also tolerate length zero in some operations to allow * bootstrapping mechanics that are currently not needed.) */ transient Node<K,V>[] table;
staticclassNode<K,V> implementsMap.Entry<K,V> { finalint hash; final K key; V value; Node<K,V> next;
publicfinal V setValue(V newValue) { VoldValue= value; value = newValue; return oldValue; }
publicfinalbooleanequals(Object o) { if (o == this) returntrue; if (o instanceof Map.Entry) { Map.Entry<?,?> e = (Map.Entry<?,?>)o; if (Objects.equals(key, e.getKey()) && Objects.equals(value, e.getValue())) returntrue; } returnfalse; } }
HashMap 静态内部类Node,实现链表,通过Node[]这个数组属性存放所有的节点。
put(K,V)
应该直接看final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict)这个方法更为实际
/** * Appends the specified element to the end of this list. * * @param e element to be appended to this list * @return <tt>true</tt> (as specified by {@link Collection#add}) */ publicbooleanadd(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; returntrue; }
privatevoidgrow(int minCapacity) { // overflow-conscious code intoldCapacity= elementData.length; intnewCapacity= oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }
publicbooleanremove(Object o) { if (o == null) { for (intindex=0; index < size; index++) if (elementData[index] == null) { fastRemove(index); returntrue; } } else { for (intindex=0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); returntrue; } } returnfalse; }
remove方法实际上就是遍历数组所有的元素,然后找到数组下标,再根据数组下标进行删除
1 2 3 4 5 6 7 8 9 10 11 12
/* * Private remove method that skips bounds checking and does not * return the value removed. */ privatevoidfastRemove(int index) { modCount++; intnumMoved= size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work }
@SuppressWarnings("unchecked") public E next() { checkForComodification(); inti= cursor; if (i >= size) thrownewNoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) thrownewConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; }
// modCount是ArrayList中的属性值,是集合添加元素、删除元素的次数,expectedModCount是迭代器中的属性值,是预期的修改次数。实际修改值与期望值不同 finalvoidcheckForComodification() { if (modCount != expectedModCount) thrownewConcurrentModificationException(); }
获取锁:如果每次申请锁的线程都是不相同的,则锁会升级为轻量级锁,指向栈中锁记录的指针。轻量级锁适用于线程交替执行同步块的场景。 释放锁:通过CAS操作,尝试把线程中复制的Displaced Mark Word对象替换当前的Mark Word,如果成功则完成解锁操作。如果失败则表明有其他线程获取该锁,此时锁膨胀为重量级锁。释放锁的同时,唤醒被挂起的线程。
重量级
当多个线程同时竞争锁,则轻量级锁会膨胀为重量级锁。指向互斥量的指针。未获取到锁的线程会阻塞。
自旋锁
循环检测锁标志位
可中断锁
Lock
1 2 3 4 5 6 7 8
// 支持中断的 API voidlockInterruptibly() throws InterruptedException; // 支持超时的 API booleantryLock(long time, TimeUnit unit) throws InterruptedException; // 支持非阻塞获取锁的 API booleantryLock();