面试题——线程池常用的阻塞队列?手写生产者消费者模式?

1. 阻塞队列

  1. ArrayBlockingQueue 数组阻塞队列:采用数组实现的有界阻塞队列,按照先进先出的原则,初始化时,需要指定容量的大小,一旦创建,容量就不能改变。采用可重入锁进行并发控制,添加和删除操作采用的是同一个锁。
  2. LinkedBlockingQueue 链表阻塞队列:采用单向链表实现的阻塞队列,可以无界也可以有界,按照先进先出的原则,默认容量为 Integer.MAX_VALUE。锁是分离的,添加和删除操作使用两个不同的锁,在高并发场景下,生产者和消费者可以并行的操作队列中的数据,所以提高了并发性能。
  3. PriorityBlockingQueue 优先级阻塞队列:支持优先级排序的阻塞队列。可以通过实现 compareTo 方法来指定元素比较规则,也可以使用 Comparator 比较器来指定比较规则。Comparable和Comparator的区别
  4. SynchronousQueue 同步队列:它是一种不保存元素的阻塞队列,通过新建一个线程来处理新任务。是一种轻量级的ArrayBlockingQueue,在只有一个生产者和一个消费者的场景下性能较好。

2. 实现生产者消费者模式

import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueTest {
    public static void main(String[] args) {
        ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
        new Thread(new Producer(queue)).start();
        new Thread(new Consumer(queue)).start();
        new Thread(new Consumer(queue)).start();
        new Thread(new Consumer(queue)).start();
    }
}

class Producer implements Runnable {

    private BlockingQueue<Integer> queue;

    public Producer(BlockingQueue<Integer> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            for (int i = 0; i < 100; i++) {
                Thread.sleep(20);
                queue.put(i);
                System.out.println(Thread.currentThread().getName() + "在生产,此时队列大小为:" + queue.size());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class Consumer implements Runnable {

    private BlockingQueue<Integer> queue;

    public Consumer(BlockingQueue<Integer> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            while (true) {
                Thread.sleep(new Random().nextInt(1000));
                queue.take();
                System.out.println(Thread.currentThread().getName() + "在消费,此时队列大小为:" + queue.size());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

你可能感兴趣的:(06,并发多线程)