Conllection---List、queue

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是滿了以後阻塞
        
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章