Concurrent包

Posted alen-apple

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Concurrent包相关的知识,希望对你有一定的参考价值。

一、概述

1.是JDK1.5出现的专门应对高并发的包

2.内容(5个):BlockingQueue阻塞队列、ConcurrentMap并发映射、ExectorService执行器服务、Lock锁、原子性操作

 

BlockingQueue-阻塞式队列: 

1.依然遵循“先进先出”(FIFO)的原则

2.所有的阻塞式队列都是有界的 - 即队列的大小是固定的

3.如果队列已满,则添加操作会被阻塞;如果队列为空,则获取操作会被阻塞

4.BlockingQueue是阻塞式队列的顶级接口,用的是其实现类

5.重要方法

  抛出异常 返回值 阻塞 定时阻塞
添加 add off - true/false put off
获取 remove poll - null take poll

 

二、ArrayBlockingQueue - 阻塞式顺序队列

1.底层是基于数组存储

2.使用的时候,需要指定容量,容量指定后不可变

package com.apple.queue;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * This is Description
 *
 * @author appleØ
 * @date 2020/06/06
 */
public class ArrayBlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        //创建阻塞式队列
        ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(5);

        //队列为空,则抛出异常
        //System.out.println(queue.remove());
        //队列为空,则返回null
        //System.out.println(queue.poll());
        //队列为空,产生阻塞
        //System.out.println(queue.peek());
        //定时阻塞
        System.out.println(queue.poll(5, TimeUnit.SECONDS));

        //添加元素
//        queue.add("a");
//        queue.add("b");
//        queue.add("c");
//        queue.add("d");
//        queue.add("e");

        //如果队列已满,则抛出异常
        //queue.add("f");
        //队列已满,则返回false
        // boolean b = queue.offer("g");
        // System.out.println(b);
        //队列已满,则产生阻塞,直到队列中有元素被取出
        // queue.put("h");
        //定时阻塞
//        boolean b = queue.offer("i", 5, TimeUnit.SECONDS);
//        System.out.println(b);
//
//        System.out.println(queue);
    }
}

 

三、LinkedBlockingQueue - 阻塞式链式队列

1.底层是基于链表来存储

2.使用的时候可以指定容量也可以不指定,但是一旦指定,容量不可变。

   如果不指定容量,默认是 Integer.MAX_VALUE -> 2^31-1,此时,一般会认为这个队列是无界的

 

package com.apple.queue;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * This is Description
 *
 * @author apple
 * @date 2020/06/06
 */
public class LinkedBlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        //创建阻塞式队列
        LinkedBlockingQueue<String> queue =
                new LinkedBlockingQueue<>();

        //队列为空,则抛出异常
        //System.out.println(queue.remove());
        //队列为空,则返回null
        //System.out.println(queue.poll());
        //队列为空,产生阻塞
        //System.out.println(queue.peek());
        //定时阻塞
        System.out.println(queue.poll(5, TimeUnit.SECONDS));

        //添加元素
//        queue.add("a");
//        queue.add("b");
//        queue.add("c");
//        queue.add("d");
//        queue.add("e");

        //如果队列已满,则抛出异常
        //queue.add("f");
        //队列已满,则返回false
        // boolean b = queue.offer("g");
        // System.out.println(b);
        //队列已满,则产生阻塞,直到队列中有元素被取出
        // queue.put("h");
        //定时阻塞
//        boolean b = queue.offer("i", 5, TimeUnit.SECONDS);
//        System.out.println(b);
//
//        System.out.println(queue);
    }
}

 

四、PriorityBlockingQueue - 具有优先级的阻塞式队列

1. 在使用的时候可以不指定容量也可以指定容量。如果不指定,默认容量DEFAULT_INITIAL_CAPACITY=11

2.在遍历队列的时候,会对放入其中的元素进行自然排序。但是注意,如果是迭代遍历,则不保证排序

3.要求放入的元素所对应的类必须实现Comparable接口

package com.apple.queue;

import java.util.concurrent.PriorityBlockingQueue;

/**
 * This is Description
 *
 * @author apple
 * @date 2020/06/06
 */
public class PriorityBlockingQueueDemo {

    public static void main(String[] args) throws InterruptedException {

        /*PriorityBlockingQueue<String> queue = new PriorityBlockingQueue<>();

        queue.put("h");
        queue.put("a");
        queue.put("e");
        queue.put("u");
        queue.put("s");
        queue.put("i");
        queue.put("p");
        queue.put("q");

        for (int i = 0; i < 8; i++) {
            System.out.println(queue.take());
        }*/

        PriorityBlockingQueue<Student> queue = new PriorityBlockingQueue<>();
        queue.add(new Student("林黛玉", 18, 90));
        queue.add(new Student("贾宝玉", 18, 50));
        queue.add(new Student("薛宝钗", 20, 80));
        queue.add(new Student("刘姥姥", 80, 15));
        queue.add(new Student("王熙凤", 28, 70));

        for (int i = 0; i < 5; i++) {
            System.out.println(queue.take());
        }

        //增强 for 循环 是迭代,不进行排序
        for (Student s : queue) {
            System.out.println(s);
        }

    }
}

class Student implements Comparable<Student> {
    private String name;
    private int age;
    private int score;

    public Student() {
    }

    public Student(String name, int age, int score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name=‘" + name + ‘‘‘ +
                ", age=" + age +
                ", score=" + score +
                ‘}‘;
    }

    /**
     * this - o 升序
     * o - this 降序
     *
     * @param o
     * @return
     */
    @Override
    public int compareTo(Student o) {
        return this.age - o.age;
    }
}

 

五、SynchronousQueue - 同步队列

1.在使用的时候不需要指定容易,容量默认为1并且只能为1

2.会把这个队列称之为汇合点

 

六、BlockingDeque - 阻塞式双端队列

1.两个方向都可以进行添加或者移除操作

以上是关于Concurrent包的主要内容,如果未能解决你的问题,请参考以下文章

# Java 常用代码片段

如何使用 java.util.concurrent 包实现后台线程?

Java源码之 java.util.concurrent 学习笔记01

Java学习笔记—多线程(java.util.concurrent.locks包,转载)

JDK源码JDK的java.util.concurrent包结构

并发包java.util.concurrent.locks.Lock