Multithreading note 5 wait notify blocking queue

Object O = new new Object ();
o.wait ();
o.notify ();
o.notifyAll ();
the wait method and notify (meaning "notification") method belong object.

When A thread calls o.wait (), A will be automatically released from the CPU state and becomes Waiting Runnable state, o wait a directing object set, A will be transferred to the wait set.

When B thread calls o.notify (); when will randomly wake up a thread waiting on the set, but o.notifyAll (); it will wake up all the threads, no effect on B itself.

Because of the above three methods are set to wait for generating a modified object, so a predetermined before using the above method, must be locked.
the synchronized (O) {
o.wait () // will wait before giving up CPU internal unlock the lock, the thread Upon wakeup
} // request which will lock again, and executes the UNLOCK
the synchronized (O) {
o.notify ( )
}
Here Insert Picture Description

import java.util.Scanner;

/*
单生产者-单消费者情况

1. 是不是线程安全的?   是否有共享,是否有修改?
2. 怎么修改成线程安全的版本? 通过加锁解决
                              volatile 不可以解决问题
3. 生产者在队列满时等待-消费者在队列空时等待
4. 生产者需要唤醒可能在等消费者;消费者需要唤醒可能在等的生产者
*/
public class MyBlockingArrayQueue {
    int[] array = new int[10];  // 下标处的数据可能出现生产者和消费者修改同一处的情况
    int front = 0;  // 只有消费者修改 front
    int rear = 0;   // 只有生产者修改 rear
    int size = 0;   // size 是生产者消费者都会修改的

    // 生产者才会调用 put
    synchronized void put(int value) throws InterruptedException {
        // 考虑满的情况
        if (size == array.length) {
            // 队列已满
            //throw new RuntimeException("队列已满"); //满了
            wait(); //停
        }

        array[rear] = value;
        rear++;
        if (rear == array.length) {
            rear = 0;
        }
        //rear = (rear + 1) % array.length;
        size++;     // 我们需要保障的是 size++ 的原子性,所以 volatile 无法解决
        notify();
    }

    // 调用 take 的一定是消费者
    synchronized int take() throws InterruptedException {
        // 考虑空的情况
        if (size == 0) {
            // 空的
            //throw new RuntimeException("队列已空");
            wait();
        }

        int value = array[front];
        front++;
        if (front == array.length) {
            front = 0;
        }
        //front = (front + 1) % array.length;
        size--;
        notify();

        return value;
    }

    static MyBlockingArrayQueue queue = new MyBlockingArrayQueue();

    static class Producer extends Thread {
        @Override
        public void run() {
            try {
                for (int i = 0; i < 100; i++) {
                    System.out.println("准备放入 " + i);
                    queue.put(i);
                    System.out.println("放入成功");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Producer producer = new Producer();
        producer.start(); //生产者启动

        Thread.sleep(2 * 1000);

        Scanner scanner = new Scanner(System.in);//消费者手动控制
        while (true) {
            scanner.nextLine();
            System.out.println(queue.take());
        }
    }
}

It synchornized not takes the time to ensure that the plus, plus when can not take.
Wait in take, put methods, notify, it is to ensure that the blocking, the increase is not into the full, take no space-time, a thread wait, to wait for another thread calls the end of the corresponding method notify to wake up.

When many to many, may appear producer wake producers, consumers wake situation of consumers at this time will lead to thread-safe, because random variations in size, the solution is in the wait thread wakes up again to determine the conditions, that is, if replaced while.

There are many to many kinds of situations is that all consumers are in wait (queue has been empty when consumers grab cpu), then producers in the queue to fill up wake producers, so that all producers are also in the wait, causing the entire program stopped. The solution is to notify change notifyAll.

java in order ArrayBlockingQueue blocking queue table implementation
LinkedBlockingQueue list implementation
PriorityBlockingQueue stack implemented

Published 15 original articles · won praise 0 · Views 260

Guess you like

Origin blog.csdn.net/rushrush1/article/details/104878573