Multi-Programming-8 线程安全类实现生产者和消费者

1.线程安全类 ArrayBlockingQueue

java.util.concurrent.BlockingQueue<Integer>

    A java.util.Queue that additionally supports operations that wait for the queue to become non-empty when retrieving an element, and wait for space to become available in the queue when storing an element.

    BlockingQueue methods come in four forms, with different ways of handling operations that cannot be satisfied immediately, but may be satisfied at some point in the future: one throws an exception, the second returns a special value (either null or false, depending on the operation), the third blocks the current thread indefinitely until the operation can succeed, and the fourth blocks for only a given maximum time limit before giving up. These methods are summarized in the following table:
    Summary of BlockingQueue methods

Throws exception Special value Blocks Times out

Tables Are Cool Cool Cool
Insert add(e) offer(e) put(e) offer(e, time,unit)
Remove remove() poll() take() poll(time, unit)
Examine element() peek() not applicable not applicable

A BlockingQueue does not accept null elements. Implementations throw NullPointerException on attempts to add, put or offer a null. A null is used as a sentinel value to indicate failure of poll operations.

A BlockingQueue may be capacity bounded. At any given time it may have a remainingCapacity beyond which no additional elements can be put without blocking. A BlockingQueue without any intrinsic capacity constraints always reports a remaining capacity of Integer.MAX_VALUE.

BlockingQueue implementations are designed to be used primarily for producer-consumer queues, but additionally support the java.util.Collection interface. So, for example, it is possible to remove an arbitrary element from a queue using remove(x). However, such operations are in general not performed very efficiently, and are intended for only occasional use, such as when a queued message is cancelled.

BlockingQueue implementations are thread-safe. 

2. 代码实现

package com.fqyuan.blog;

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

public class ConcurrentQueue {

    public static void main(String[] args) {
        ConcurrentQueueUtil.demonstrate();
    }

}

class SharedObjectCon {
    BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
    Random random = new Random();

    public void produce() throws InterruptedException {
        while (true) {
            Thread.sleep(80);
            if (random.nextDouble() < 0.1)
                queue.put(random.nextInt(100));
        }
    }

    public void consume() throws InterruptedException {
        while (true) {
            Thread.sleep(100);
            if (random.nextInt(10) < 1) {
                int val = queue.take();
                System.out.println("Value taken is " + val + "; queue size is " + queue.size());
            }

        }
    }
}

class ConcurrentQueueUtil {
    public static void demonstrate() {
        SharedObjectCon sharedObjectCon = new SharedObjectCon();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    sharedObjectCon.produce();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    sharedObjectCon.consume();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
        t1.start();
        t2.start();
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

运行结果:

Value taken is 67; queue size is 0
Value taken is 19; queue size is 0
Value taken is 79; queue size is 2
Value taken is 76; queue size is 8
Value taken is 16; queue size is 8
Value taken is 18; queue size is 9
Value taken is 89; queue size is 8
Value taken is 27; queue size is 10
Value taken is 41; queue size is 9
Value taken is 40; queue size is 9
Value taken is 23; queue size is 9
Value taken is 82; queue size is 9

3.Why not common containers like List?

List不是线程安全的。

相关问题参见疑问。
What does it mean array list is synchronized in java?
It means it is thread-safe.

Vectors are synchronized. Any method that touches the Vector's contents is thread safe.
ArrayList, on the other hand, is unsynchronized, making them, therefore, not thread safe.

相关代码实现,点击 这里。

你可能感兴趣的:(线程安全,Class)