**
【集合】ArrayList 10連問
**
List list = new ArrayList();
1問:當我們new了一個ArrayList,底層new了一個什么?new了一個陣列
2問:什么型別的陣列?object[]
3問 : 陣列的長度是多大?10 ;陣列長度默認是空, add 以后 底層創建了長度是10的Object[]陣列
4問:陣列的長度是10,我現在要放25, 為什么沒有報【陣列下標越界例外】 , 容量不夠,有擴容機制
5問:擴容為原來的1.5倍, ArrayList每次擴容為原值的一半,hashmap每次擴容為原值的一倍; 10 第一次擴容原值一半是 15;
6問:第二次擴容是多少?第二次擴容是15+7.5=22.5 向上取整為22;第三次擴容為33
7問:有沒有看過ArrayList底層原始碼? 有,擴容是怎么擴的? 底層用的是什么方法? 底層用的是Arrays.copyOf
elementData = Arrays.copyOf(elementData, size, Object[].class);
8問:ArrayList 是執行緒安全的還是執行緒不安全的? ArrayList是執行緒不安全的,你確定嗎? 我確定
9問:請你寫一個執行緒不安全的case,會報什么故障,怎么處理?
會報:java.util.ConcurrentModificationException【并發修改例外】
解決:使用juc的寫時復制技術
List list = new CopyOnWriteArrayList();//寫時復制【讀寫分離】
//解決方案一
//List list = new Vector();//Vector 不使用 JDK1.0 版本低
//解決方案二
//List list = Collections.synchronizedList(new ArrayList<>());
//解決方案三
List list = new CopyOnWriteArrayList();//寫時復制
NotSaftDemo
//方式一:使用lambda運算式
for(i=1,i<=30,i++)
{
new Thread(() -> {
list.add(UUID.randomUUID().toString().substring(0, 8));
sout(list);
}, String.valueOf(i)).start();
}
//方式二:實作Runnable介面
for(i=1,i<=30,i++)
{
new Thread(new Runnable() {
@Override
public void run() {
list.add(UUID.randomUUID().toString().substring(0, 8));
sout(list);
}
}, String.valueOf(i)).start();
}
10問:你了解什么是寫時復制技術?談談你的理解?
ArrayList 舉例子:簽到名單
筆記
- 寫時復制
CopyOnWrite容器即寫時復制的容器,往一個容器添加元素的時候,不直接往當前容器Object[]添加,而是先將當前容器Object[]進行Copy,
復制出一個新的容器Object[] newElements,然后新的容器Object[] newElements里添加元素,添加完元素之后,
再將原容器的參考指向新的容器 setArray(newElements);,這樣做的好處是可以對CopyOnWrite容器進行并發的讀,
而不需要加鎖,因為當前容器不會添加任何元素,所以CopyOnWrite容器也是一種讀寫分離的思想,讀和寫不同的容器
{
final ReentrantLock lock = this.lock;
lock.lock();
try
{
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
}
finally {
lock.unlock();
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/229094.html
標籤:其他
下一篇:淺談手機驗證碼登錄
