并发集合:ConcurentLinkedDeque

来源:互联网 发布:丁丁停车关闭 知乎 编辑:程序博客网 时间:2024/06/16 03:20

阻塞式集合:这类集合包括添加和移除数据的方法。当集合已满或者为空时,被调用的添加或者移除方法不能立即被执行,那么调用这个方法的线程被阻塞,一直到该方法可以被成功执行。如LinkedBlockingDeque\PriorityBlockingQueue
非阻塞式集合:这类集合也包括添加和移除数据的方法。如果方法不能立即被执行,则返回null或抛出异常,但调用这个方法的线程不会被阻塞。如ConcurentLinkedDeque\DelayQueue

ConcurrentLinkedDeque/LinkedBlockingDeque

package mytest;import java.util.concurrent.ConcurrentLinkedDeque;/** * ConcurentLinkedDeque: 线程安全的、非阻塞式的、双端、无界队列<br> *  * peek()/peekFirst()/peekLast:返回列表中第一个或最后一个,返回的元素不会从列表中移除,如果列表为空,则返回null * getFirst/getLast:返回列表中第一个或最后一个,返回的元素不会从列表中移除,如果列表为空,则抛出NoSuchElementException *  * pollFist/pollLast:移除元素,如果列表为空,则返回null * removeFirst/removeLast/remove:移除元素,如果列表为空,则抛出NoSuchElementException *  */public class ConcurentLinkedDequeTest {    private static ConcurrentLinkedDeque<Integer> cld = new ConcurrentLinkedDeque<Integer>();    //可以指定队列大小,不指定时,为Integer.MAX_VALUE.Blocking意味着会有阻塞机制    private static LinkedBlockingDeque<Integer> lbd = new LinkedBlockingDeque<Integer>();    static class AddTask implements Runnable {        public void run() {            for (int i = 0; i < 1000; i++) {                cld.add(i);            }        }    }    static class PollTask implements Runnable {        public void run() {            for (int i = 0; i < 500; i++) {                cld.pollFirst();                cld.pollLast();                cld.pollLast();            }        }    }    public static void main(String[] args) {        // 创建添加线程任务        Thread[] threads = new Thread[10];        for (int i = 0; i < threads.length; i++) {            Thread at = new Thread(new AddTask());            threads[i] = at;            threads[i].start();        }        System.out.println("add task threads have been lauched.count:" + threads.length);        for (int i = 0; i < threads.length; i++) {            try {                threads[i].join();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        System.out.println("size of list :" + cld.size());        for (int i = 0; i < threads.length; i++) {            Thread at = new Thread(new PollTask());            threads[i] = at;            threads[i].start();        }        System.out.println("poll task threads have been lauched.count:" + threads.length);        for (int i = 0; i < threads.length; i++) {            try {                threads[i].join();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        System.out.println("size of list :" + cld.size());    }}

输出

add task threads have been lauched.count:10
size of list :10000
poll task threads have been lauched.count:10
size of list :0

PriorityBlockingQueue

package mytest;import java.util.concurrent.PriorityBlockingQueue;//有序组合队列//当插入元素时,PriorityBlockingQueue使用compareTo方法来决定插入元素的位置,元素越大越靠后public class PriorityBlockingQueueTest {    static class Event implements Comparable<Event> {        private int thread;        private int priority;        public Event(int thread, int priority) {            this.thread = thread;            this.priority = priority;        }        public int getThread() {            return thread;        }        public int getPriority() {            return priority;        }        @Override        public int compareTo(Event o) {            if (this.priority > o.getPriority()) {                return -1;            } else if (this.priority < o.getPriority()) {                return 1;            }            return 0;        }    }    static class Task implements Runnable {        private int id;        private PriorityBlockingQueue queue;        public Task(int id, PriorityBlockingQueue<Event> queue) {            this.id = id;            this.queue = queue;        }        @Override        public void run() {            for (int i = 0; i < 100; i++) {                Event event = new Event(id, i);                queue.add(event);            }        }    }    public static void main(String[] args) {        PriorityBlockingQueue<Event> queue = new PriorityBlockingQueue<Event>();        Thread taskThread[] = new Thread[5];        for (int i = 0; i < taskThread.length; i++) {            Task task = new Task(i, queue);            taskThread[i] = new Thread(task);        }        for (int i = 0; i < taskThread.length; i++) {            taskThread[i].start();        }        for (int i = 0; i < taskThread.length; i++) {            try {                taskThread[i].join();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        for (int i = 0; i < taskThread.length * 100; i++) {            Event poll = queue.poll();            System.out.println("thread :" + poll.getThread() + ";priority:" + poll.getPriority());        }    }}

输出结果

thread :1;priority:99
thread :4;priority:99
thread :2;priority:99
thread :0;priority:99
thread :3;priority:99
thread :1;priority:98
thread :4;priority:98
thread :2;priority:98
thread :0;priority:98
thread :3;priority:98

DelayQueue

package mytest;import java.util.Date;import java.util.concurrent.DelayQueue;import java.util.concurrent.Delayed;import java.util.concurrent.PriorityBlockingQueue;import java.util.concurrent.TimeUnit;//DelayQueue中的元素必须继承Delayed接口。该接口使对象成为延迟对象,它使放在DelayQueue中的对象具有激活日期//未到期的元素你是获取不到嘀public class DelayQueueTest {    static class Event implements Delayed {        private Date startDate;        public Event(Date startDate) {            this.startDate = startDate;        }        @Override        public int compareTo(Delayed o) {            // 将毫秒转换成纳秒进行比较            long result = this.getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);            if (result < 0) {                return -1;            } else if (result > 0) {                return 1;            }            return 0;        }        @Override        public long getDelay(TimeUnit unit) {            Date now = new Date();            long diff = startDate.getTime() - now.getTime();            return unit.convert(diff, TimeUnit.MILLISECONDS);// 激活日期到当前日期的毫秒数;diff和第二个参数类型一致        }    }    static class Task implements Runnable {        private int id;        private DelayQueue queue;        public Task(int id, DelayQueue<Event> queue) {            this.id = id;            this.queue = queue;        }        @Override        public void run() {            Date now = new Date();            Date delay = new Date();            delay.setTime(now.getTime() + (id * 5000));            System.out.println("Thread id:" + id + ";delay:" + delay);            for (int i = 0; i < 100; i++) {                Event event = new Event(delay);                queue.add(event);            }        }    }    public static void main(String[] args) throws InterruptedException {        Date now = new Date();        long minutes = TimeUnit.HOURS.toMinutes(1);        System.out.println(minutes);        System.out.println(TimeUnit.NANOSECONDS.convert(1000L, TimeUnit.MILLISECONDS));        DelayQueue<Event> queue = new DelayQueue<Event>();        Thread taskThread[] = new Thread[5];        for (int i = 0; i < taskThread.length; i++) {            Task task = new Task(i + 1, queue);            taskThread[i] = new Thread(task);        }        for (int i = 0; i < taskThread.length; i++) {            taskThread[i].start();        }        for (int i = 0; i < taskThread.length; i++) {            try {                taskThread[i].join();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        do {            int counter = 0;            Event event;            do {                // 只取已经到了激活时间的event                event = queue.poll();                if (event != null)                    counter++;            } while (event != null);            System.out.println("At " + new Date() + " you have read " + counter + " events");            TimeUnit.SECONDS.sleep(1);//休息1秒尝试取一次        } while (queue.size() > 0);// 一直等到将队列取光    }}

结果:可见5秒钟激活一组数据

At Tue Mar 21 15:48:32 CST 2017 you have read 0 eventsAt Tue Mar 21 15:48:33 CST 2017 you have read 0 eventsAt Tue Mar 21 15:48:34 CST 2017 you have read 0 eventsAt Tue Mar 21 15:48:35 CST 2017 you have read 0 eventsAt Tue Mar 21 15:48:36 CST 2017 you have read 0 eventsAt Tue Mar 21 15:48:37 CST 2017 you have read 100 eventsAt Tue Mar 21 15:48:38 CST 2017 you have read 0 eventsAt Tue Mar 21 15:48:39 CST 2017 you have read 0 eventsAt Tue Mar 21 15:48:40 CST 2017 you have read 0 eventsAt Tue Mar 21 15:48:41 CST 2017 you have read 0 eventsAt Tue Mar 21 15:48:42 CST 2017 you have read 100 events
0 0