Java 多線程編程 通過 ReentrantLock鎖, 實現阻塞隊列

Java 多線程編程 通過 ReentrantLock鎖, 實現阻塞隊列

1. 自定義簡單阻塞隊列實現類


import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class CustomBlockingQueue<T> {
    /** 隊列長度*/
    private final int size;

    /** 鏈表用於保存數據*/
    private final LinkedList<T> list = new LinkedList<>();

    /** 重入鎖*/
    private final Lock lock = new ReentrantLock();

    /** 隊列滿時的等待條件*/
    private final Condition notFull = lock.newCondition();

    /** 隊列空時的等待條件*/
    private final Condition notEmpty = lock.newCondition();

    public CustomBlockingQueue(final int size) {
        this.size = size;
    }

    /**
     * 如果隊列滿, 則阻塞
     * */
    public void add(T value) throws InterruptedException {
        lock.lock();
        try {
            while(list.size() == size) {
                System.out.println("隊列已滿 -- 入隊過程進入等待");
                notFull.await();
            }
            /** 入隊到鏈表末尾*/
            list.add(value);
            /** 喚醒在 notEmpty條件內等待的線程*/
            notEmpty.signal();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 如果隊列爲空, 則阻塞
     * */
    public T take() throws InterruptedException {
        T value;
        lock.lock();
        try {
            while(list.size() == 0) {
                System.out.println("隊列爲空 -- 出隊過程進入等待");
                notEmpty.await();
            }
            /** 移除並返回鏈表頭部的元素*/
            value = list.removeFirst();
            /** 喚醒在 notFull條件內等待的線程*/
            notFull.signal();
        } finally {
            lock.unlock();
        }

        return value;
    }

}

2. App.java


public class App {
    public static void main(String[] args) {
        final CustomBlockingQueue<Integer> queue = new CustomBlockingQueue<>(3);

        /** 多線程入隊*/
        new Thread(() -> {
            for (int i = 0; i < 100; i++) {
                System.out.println("入隊: " + i);
                try {
                    queue.add(i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        /** 多線程出隊*/
        new Thread(() -> {
            for(int i = 0; i < 100; i++) {
                try {
                    System.out.println("出隊: " + queue.take());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

}

如果您覺得有幫助,歡迎點贊哦 ~ 謝謝!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章