Conllection---List、queue

原创
2020/08/04 14:55
阅读数 32

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是满了以后阻塞
        
    }
}

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部