Java

java多线程-03-阻塞队列简介

2016-12-04  本文已影响56人  hylexus

[TOC]

声明

该系列文章只是记录本人回顾java多线程编程时候记录的笔记。文中所用语言并非严谨的专业术语(太严谨的术语其实本人也不会……)。难免有理解偏差的地方,欢迎指正。
另外,大神请绕路。不喜勿喷。
毕竟好记性不如烂笔头嘛,而且许多东西只要不是你经常用的最终都会一丢丢一丢丢地给忘记。

** 初看之下,阻塞队列似乎和多线程没有多大关系。但是平时使用阻塞队列的场景往往是和线程相关的。所以,此处将阻塞队列也归入java多线程的分类。 **

1 什么是阻塞队列

说白了,阻塞队列还是一个队列(FIFO)。至于队列的概念就不多说了。
阻塞队列和普通队列的区别就在阻塞这个词。

阻塞的意思,可以这么理解:

2 JDK提供的阻塞队列

2.1 JDK内置的阻塞队列

2.2 阻塞队列不可用时的处理方式

此处要说的是,队列在特殊情况下的出队入队操作的处理。
比如在队列为空或者队列已经满了的时候不同的阻塞队列实现或者不同的方法会有不同的处理方式。

对这种特殊情况的处理,大致有以下一些方法:

以下图片是来自《Java并发编程的艺术》一书中的总结:

这队列特殊情况的处理

3 使用示例

以上介绍的七种JDK内置的阻塞队列,各有各的使用场景,一篇文章很难介绍清楚。
以后会抽空补全各种阻塞队列的使用场景示例。

此处,就修改一下上篇文章线程通信中那个生产者和消费者的示例程序(http://blog.csdn.net/hylexus/article/details/53446711)。

和上篇文章的不同之处在于,此处使用阻塞队列来代替上篇文章中简单实现的一个数据结构栈。
Container类的实现修改成了下面的样子:

public static class Container {
    private ArrayBlockingQueue<Product> products;

    public Container(int size) {
        this.products = new ArrayBlockingQueue<>(size);
    }

    public void put(Product product) {
        try {
            this.products.put(product);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public Product get() {
        try {
            return this.products.take();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }
}

完整的代码示例如下:

import java.util.concurrent.ArrayBlockingQueue;

public class ProducerConsumerByLockingQueue {

    public static void main(String[] args) {
        Container container = new Container(5);
        for (int i = 0; i < 10; i++) {
            new Thread(new Producer(container), "P-" + i).start();
            new Thread(new Consumer(container), "C-" + i).start();
        }
    }

    public static class Product {
        private String name;

        public Product(String name) {
            super();
            this.name = name;
        }

        public String getName() {
            return name;
        }

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

        @Override
        public String toString() {
            return "[name=" + name + "]";
        }

    }

    public static class Container {
        private ArrayBlockingQueue<Product> products;

        public Container(int size) {
            this.products = new ArrayBlockingQueue<>(size);
        }

        public void put(Product product) {
            try {
                this.products.put(product);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public Product get() {
            try {
                return this.products.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    public static class Producer implements Runnable {

        private Container container;

        public Producer(Container container) {
            super();
            this.container = container;
        }

        @Override
        public void run() {
            for (int i = 0; i < Integer.MAX_VALUE; i++) {
                Product p = new Product(Thread.currentThread().getName() + "_" + i);
                this.container.put(p);
                System.out.println("生产者[" + Thread.currentThread().getName() + "]生产>>>>>>:" + p);
                try {
                    Thread.sleep((long) (Math.random() * 1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    public static class Consumer implements Runnable {

        private Container container;

        public Consumer(Container container) {
            super();
            this.container = container;
        }

        @Override
        public void run() {
            for (int i = 0; i < Integer.MAX_VALUE; i++) {
                Product product = this.container.get();
                System.out.println("消费者[" + Thread.currentThread().getName() + "]消费<<<<<<:" + product);
                try {
                    Thread.sleep((long) (Math.random() * 2000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

参考资料

上一篇 下一篇

猜你喜欢

热点阅读