[轉]MyBatis - MyBatis使用log4j2顯示sql和結果集
阿新 • • 發佈:2020-12-11
執行緒安全的集合
- CopyOnWriteArrayList
- 執行緒安全的ArrayList,加強版的讀寫分離。
- 寫有鎖,讀無鎖,讀寫之間不阻塞,由於讀寫鎖。
- 寫入時,先copy一個容器副本、再新增新元素,最後替換引用。(浪費空間)
- 使用方式與ArrayList無異。
package com.sun.base.XianCheng; import java.util.List; import java.util.Random; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 使用多執行緒操作CopyOnWriteArrayList */ public class Mylist { public static void main(String[] args) { //建立集合 List<String> list=new CopyOnWriteArrayList<>(); //建立執行緒池 ExecutorService es = Executors.newFixedThreadPool(5); //提交任務 for (int i=0;i<5;i++){ es.submit(new Runnable() { @Override public void run() { for (int j =0;j<10;j++){ list.add(Thread.currentThread().getName()+"---"+new Random().nextInt(1000)); } } }); } //關閉執行緒池 es.shutdown(); while (!es.isTerminated()){} //列印結果 System.out.println(list.size()); for (String str:list) { System.out.println(str.toString()); } } }
- CopyOnWriteArraySet
- 執行緒安全的Set,底層使用CopyOnWriteArrayList實現。
- 唯一不同在於,使用addIfAbsent()新增元素,會遍歷陣列,如存在元素,則不新增(扔掉副本)。
- 重複依據:equals方法。
package com.sun.base.XianCheng; import java.util.concurrent.CopyOnWriteArraySet; /** * 演示CopyOnWriteArraySet */ public class MySet { public static void main(String[] args) { //建立集合 CopyOnWriteArraySet<String> strings = new CopyOnWriteArraySet<>(); //新增元素 strings.add("aaa"); strings.add("bbb"); strings.add("ccc"); strings.add("ddd"); strings.add("aaa"); //列印 System.out.println("元素個數:"+strings.size()); System.out.println(strings.toString());//有序 } }
Queue介面(佇列)
-
Collection的子介面,表示佇列FIFO(先進先出)
-
常見方法:
- 丟擲異常:
- boolean add(E e)//順序新增一個元素(到達上限後,再新增則會丟擲異常)
- E remove()//獲得第一個元素並移除(如果佇列沒有元素時,則丟擲異常)
- E element()//獲得第一個元素但不移除(如果佇列沒有元素時,則會丟擲異常)
- 返回特殊值:推薦使用
- boolean offer(E e)//順序新增一個元素(到達上限後,再新增則會返回false)
- E poll()//獲得第一個元素並移除(如果佇列沒有元素時,則返回null)
- E peek()//獲得第一個元素但不移除(如果佇列沒有元素時,則返回null)
- 丟擲異常:
-
ConcurrentLinkedQueue
- 執行緒安全、可高效讀寫的佇列,高併發下效能最好的佇列。
- 無鎖、CAS比較交換演算法,修改的方法包含三個核心引數(V,E,N)
- V:要更新的變數;E:預期值;N:新值。
- 只有當VE時,VN;否則表示已被更新過,則取消當前操作。
package com.sun.base.XianCheng;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* ConcurrentLinkedQueue的使用
*/
public class MyConcurrentLinkedQueue {
public static void main(String[] args) throws InterruptedException {
//建立安全佇列
ConcurrentLinkedQueue<Integer> integers = new ConcurrentLinkedQueue<>();
//建立執行緒
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i <= 5; i++) {
integers.offer(i);
}
}
});
Thread thread1=new Thread(new Runnable() {
@Override
public void run() {
for (int i = 6; i <= 10; i++) {
integers.offer(i);
}
}
});
//啟動執行緒
thread.start();
thread1.start();
thread.join();
thread1.join();
//出隊
int size=integers.size();
for (int i=0;i<size;i++){
System.out.println(integers.poll());
}
}
}
-
BlockingQueue介面(阻塞佇列)
-
Queue的子介面,阻塞的佇列,增加了兩個執行緒狀態為無限期等待的方法。
-
方法:
- void put(E,e) //將指定的元素插入次佇列中,如果沒有可用空間,則等待。
- E take() //獲取並移除次佇列頭部元素,如果沒有可用元素,則等待。
-
可用於解決生產者、消費者問題。
-
實現類
-
ArrayBlockingQueue:陣列結構實現,有界佇列。(手工固定上限)
package com.sun.base.XianCheng; import java.util.concurrent.ArrayBlockingQueue; /** * 阻塞佇列的使用 * 案例1:實現生產者和消費者 */ public class MyBlockingQueue { public static void main(String[] args) throws InterruptedException { //建立一個有界佇列 ArrayBlockingQueue<Integer> strings = new ArrayBlockingQueue<>(6);//固定麵包上限為6 //建立兩個執行緒 Thread t1=new Thread(new Runnable() { @Override public void run() { for (int i=1;i<20;i++){ try { strings.put(i); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"生產了第"+i+"號麵包"); } } },"小明"); Thread t2=new Thread(new Runnable() { @Override public void run() { for (int i=1;i<20;i++){ try { strings.take(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"消費了第"+i+"號麵包"); } } },"小紅"); t1.start(); t2.start(); } }
-
LinkedBlockingQueue:連結串列結構實現,有界佇列。(預設上限Integer.MAX_VALUE)
-
-
-
ConcurrentHashMap
- 初始容量預設為16段(Segment),使用分段鎖設計。
- 不對整個Map加鎖,而是為每個Segment加鎖。
- 當多個物件存入同一個Segment時,才需要互斥。
- 最理想狀態為16個物件分別存入16個Segment,並行數量16。
- 使用方式與HashMap無異。
package com.sun.base.XianCheng;
import java.util.concurrent.ConcurrentHashMap;
/**
* ConcurrentHashMap的使用
*/
public class MyConcurrentHashMap {
public static void main(String[] args) {
//建立集合
ConcurrentHashMap<String, String> hashMap = new ConcurrentHashMap<>();
//使用多執行緒新增資料
for (int i=0;i<5;i++){
new Thread(new Runnable() {
@Override
public void run() {
for (int j=0;j<4;j++){
hashMap.put(Thread.currentThread().getName()+"---"+j,j+" ");
System.out.println(hashMap);
}
}
}).start();
}
}
}