多線程高併發筆記三

Queue: (數組,鏈表)  ConcurrentLinkedQueue

import java.util.Queue;
import java.util.concurrent.*;

public class QueueTest {
    private static Queue<String> total = new ConcurrentLinkedQueue<>();//單向隊列
    private static Queue<String> total1 = new ConcurrentLinkedDeque<>();//雙向隊列

    /**
     * 非併發,不加鎖:ArrayList,LinkedList
     * 併發小:Collections.synchronizedXXX
     * 讀取量特別大,寫入量特別少:CopyOnWriteXXXX
     * 高併發用的多的隊列
     *  Queue:
     *    ConcurrentLinkedQueue 併發加鎖,非阻塞
     *    BlockingQueue: 阻塞隊列  put如果滿了,新線程進來就會等待; take如果拿了,新線程進來就會等待
     *      LinkedBlockingQueue:無界隊列
     *      ArrayBlockingQueue:有界隊列;
     *                          如果隊列已經滿了:
     *                              add : 再加入數據會報異常
     *                              offer : 再加入數據不會報異常,但不會加入(offer還可以設置,如果多少時間內加不進去則不再加入 pp.offer("aaa",1,TimeUnit.SECONDS))
     *                              put : 加不進去,則線程阻塞
     *      DelayQueue:非阻塞,無界隊列 可以設置每個存入的數據多少時間後可以取出。每個元素需要實現Delayed類,以及實現相應方法。可以用來做定時執行任務
     *      TransferQueue: 先啓動消費者,再賦值
     *        LinkedTransferQueue:
     *      SynchronousQueue : 容量爲0的隊列,立馬交給消費者消費
     */

    static {
        for (int i=0;i<10000;i++) total.add("火車票 編號:"+(i+1));
    }

    public static void main(String[] args) throws Exception{
//        for (int i = 0;i<10;i++){
//            new Thread(()->{
//                while (true){
//                    String s = total.poll();
//                    if ( s == null) break;
//                    else System.out.println(s);
//                }
//            }).start();
//        }
        //new QueueTest1().test2();
//        new QueueTest1().test3();
        new QueueTest1().test4();
    }
}

class QueueTest1{
    void test(){
        Queue<String> queue = new ConcurrentLinkedQueue<>();
        queue.offer("hello"); //類似於 add。 但ArrayList 元素最多有個數限制。但offer可以通過返回值判斷是否加入,是無界隊列,FIFO
        String s1 = queue.peek(); //取出一個數據
        String s2 = queue.poll(); //刪除一個數據,並把刪除的數據返回
    }

    void test2() throws InterruptedException {
        BlockingQueue queue = new DelayQueue<>();
        TTT t1 = new TTT(1000L);
        TTT t2 = new TTT(2000L);
        TTT t3 = new TTT(3000L);

        queue.put(t3);
        queue.put(t2);
        queue.put(t1);
        System.out.println(queue);
        for (int i = 0;i<3;i++) System.out.println(queue.take());

    }
    class TTT implements Delayed{
        private Long waitTime;

        public TTT(Long waitTime) {
            this.waitTime = waitTime;
        }

        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(waitTime - System.currentTimeMillis(),TimeUnit.MILLISECONDS);
        }

        @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 0;
            else return 0;
        }

        @Override
        public String toString() {
            return "TTT{" +"waitTime=" + waitTime + '}';
        }
    }


    //實時消息處理用的多
    void test3(){
        TransferQueue<String> queue = new LinkedTransferQueue();
        new Thread(() ->{
            try {
                System.out.println(queue.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        try {
            queue.transfer("123"); //找不到消費者,線程將阻塞在這裏
//            queue.add("123"); //不會阻塞
//            queue.put("123");//不會阻塞
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

//        new Thread(() ->{
//            try {
//                System.out.println(queue.take());
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }).start();

    }

    void test4() throws InterruptedException {
        BlockingQueue<String> queue = new SynchronousQueue<>();

        new Thread(()->{
            try {
                queue.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        queue.put("aaa");//沒有消費者則阻塞
//        queue.add("aaa"); //會報錯 java.lang.IllegalStateException: Queue full
        System.out.println(queue.size());
    }

}

 

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