Vector:線程安全,每個方法都加sync加鎖了
Vector<String> tickets = new Vector<>();
LinkedList/ArrayList:線程不安全
List<String> tickets = new LinkedList<>();
CopyOnWriteArrayList:線程安全的,寫時複製,在寫入數據的時候,複製一個ArrayList集合,然後添加新元素,這個過程是加ReentrantLock 的,添加完成以後引用指向新的集合,所以插入數據效率比較低因爲每次都要加lock並且複製新的集合;ReentrantLock內部使用的是CAS
//源碼
public boolean add(E e) {
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();
}
}
CopyOnWriteArrayList<String> copy = new CopyOnWriteArrayList<>();
ConcurrentLinkedQueue:線程安全,內部使用CAS進行數據插入
Queue<String> tickets = new ConcurrentLinkedQueue<>();//實例化
tickets.poll();//彈出數據
public class ConcurrentQueue {
public static void main(String[] args) {
Queue<String> strs = new ConcurrentLinkedQueue<>();
for(int i=0; i<10; i++) {
strs.offer("a" + i); //add 使用offer添加數據會返回bool,成功true失敗false不會報錯,使用add添加失敗會報錯
}
System.out.println(strs);
System.out.println(strs.size());
System.out.println(strs.poll());///獲取數據並移除
System.out.println(strs.size());
System.out.println(strs.peek());//獲取數據但是不移除
System.out.println(strs.size());
//雙端隊列Deque
}
}
BlockingQueue:阻塞隊列
public class LinkedBlockingQueue {
static BlockingQueue<String> strs = new LinkedBlockingQueue<>();
static Random r = new Random();
public static void main(String[] args) {
new Thread(() -> {
for (int i = 0; i < 100; i++) {
try {
strs.put("a" + i); //如果滿了,就會等待
TimeUnit.MILLISECONDS.sleep(r.nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "p1").start();
for (int i = 0; i < 5; i++) {
new Thread(() -> {
for (;;) {
try {
System.out.println(Thread.currentThread().getName() + " take -" + strs.take()); //如果空了,就會等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "c" + i).start();
}
}
}
ArrayBlockingQueue:
public class ArrayBlockingQueue {
static BlockingQueue<String> strs = new ArrayBlockingQueue<>(10);
static Random r = new Random();
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 10; i++) {
strs.put("a" + i);
}
//strs.put("aaa"); //滿了就會等待,程序阻塞
//strs.add("aaa");//滿了添加會報錯
//strs.offer("aaa");//添加是否成功會返回bool值
strs.offer("aaa", 1, TimeUnit.SECONDS);
//strs.task();//如果空了,就會等待
//strs.peek();//獲取數據但是不移除
//strs.poll();//獲取數據並移除
}
}
PriorityQueque :底層是二叉樹,所以有順序
public class PriorityQueque {
public static void main(String[] args) {
PriorityQueue<String> q = new PriorityQueue<>();
q.add("c");
q.add("e");
q.add("a");
q.add("d");
q.add("z");
for (int i = 0; i < 5; i++) {
System.out.println(q.poll());
}
}
}
DelayQueue:延遲隊列
public class T07_DelayQueue {
static BlockingQueue<MyTask> tasks = new DelayQueue<>();
static Random r = new Random();
static class MyTask implements Delayed {
String name;
long runningTime;
MyTask(String name, long rt) {
this.name = name;
this.runningTime = rt;
}
@Override
public int compareTo(Delayed o) {
if(this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS))
return -1;
else if(this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS))
return 1;
else
return 0;
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(runningTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
@Override
public String toString() {
return name + " " + runningTime;
}
}
public static void main(String[] args) throws InterruptedException {
long now = System.currentTimeMillis();
MyTask t1 = new MyTask("t1", now + 1000);
MyTask t2 = new MyTask("t2", now + 2000);
MyTask t3 = new MyTask("t3", now + 1500);
MyTask t4 = new MyTask("t4", now + 2500);
MyTask t5 = new MyTask("t5", now + 500);
tasks.put(t1);
tasks.put(t2);
tasks.put(t3);
tasks.put(t4);
tasks.put(t5);
System.out.println(tasks);
for(int i=0; i<5; i++) {
System.out.println(tasks.take());
}
}
}
SynchronusQueue :同步隊列,先要使用strs.take()取數據,阻塞狀態,然後才能放數據,因爲SynchronousQueue容量爲0
public class SynchronusQueue { //容量爲0
public static void main(String[] args) throws InterruptedException {
BlockingQueue<String> strs = new SynchronousQueue<>();
new Thread(()->{
try {
System.out.println(strs.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
strs.put("aaa"); //阻塞等待消費者消費
System.out.println(strs.size());
}
}
TransferQueue:傳遞隊列
public class TransferQueue {
public static void main(String[] args) throws InterruptedException {
LinkedTransferQueue<String> strs = new LinkedTransferQueue<>();
new Thread(() -> {
try {
System.out.println(strs.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
strs.transfer("aaa");//使用transfer添加數據,當有人take以後才返回否則阻塞,如果使用put是滿了以後阻塞
}
}