JAVA多種方式實現 阻塞隊列(等待通知、生產消費)

實現思路:

  • 1.wait、notifyAll實現:
  • 2.Samper信號量令牌
  • 3.Lock鎖

代碼分別實現這四種

定義一個接口:

IPutGetBlock.java

public interface IPutGetBlock<I> {
    void putThread(I i) throws InterruptedException;
    I getThread() throws InterruptedException;
}

1.wait、notifyAll實現:


import java.util.LinkedList;
import java.util.List;

public class WaitNotifyBlock<E> implements IPutGetBlock<E>{

    private List queue = new LinkedList();
    private int limit=0;

    public WaitNotifyBlock(int limit) {
        this.limit = limit;
    }

    @Override
    public synchronized void putThread(E o) throws InterruptedException {
        while (queue.size()>=limit)
            wait();
        queue.add(o);
        notifyAll();
    }

    @Override
    public synchronized E getThread() throws InterruptedException {
        while (queue.size()==0)
            wait();
        E e = (E) queue.remove(0);
        notifyAll();
        return e;
    }
}

2.Samper信號量令牌

 com.bruce.chen.part3.ch10.block;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Semaphore;

public class SemphoreBlock<E> implements IPutGetBlock<E> {

    private Semaphore items, spaces;

    private List queue = new LinkedList<>();

    public SemphoreBlock(int items) {
        this.spaces = new Semaphore(items);
        this.items = new Semaphore(0);
    }


    @Override
    public void putThread(E e) throws InterruptedException {
        spaces.acquire();
        synchronized (this) {
            queue.add(e);
        }
        items.release();
    }

    @Override
    public E getThread() throws InterruptedException {
        items.acquire();
        E e;
        synchronized (this) {
            e = (E) queue.remove(0);
        }
        spaces.release();
        return e;
    }

}




3.Lock鎖
LockConditionBlock

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

public class LockConditionBlock<E> implements IPutGetBlock<E>{

    private List<E> queue = new LinkedList<E>();
    private int limit = 2;

    private Lock lock = new ReentrantLock();
    private Condition notFull = lock.newCondition();
    private Condition notEmpty = lock.newCondition();

    public LockConditionBlock() {
        this(2);
    }

    public LockConditionBlock(int limit) {
        this.limit = limit;
    }

    @Override
    public void putThread(E e) throws InterruptedException {
        lock.lock();
        try {
            while(queue.size()==limit){
                notFull.await();
            }
            queue.add(e);
            notEmpty.signal();
        }finally {
            lock.unlock();
        }

    }

    @Override
    public E getThread() throws InterruptedException {
        lock.lock();
        try {
            while (queue.size() == 0) {
                notEmpty.await();
            }
            E e = queue.remove(0);
            notFull.signal();
            return e;
        }finally {
            lock.unlock();
        }

    }

}

test測試:
MyTest.class

public class MyTest {

    static class PutThread extends Thread{

        private IPutGetBlock<String> iPutGetBlock;

        public PutThread(IPutGetBlock<String> iPutGetBlock) {
            this.iPutGetBlock = iPutGetBlock;
        }

        @Override
        public void run() {
            super.run();
//            while (!Thread.currentThread().isInterrupted()){
                for (int i = 0; i < 10; i++) {
                    try {
                        iPutGetBlock.putThread("i="+i);
                        System.out.println("生產=i="+i);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
//            }

        }
    }

    static class TaskThread extends Thread{

        private IPutGetBlock<String> iPutGetBlock;

        public TaskThread(IPutGetBlock<String> iPutGetBlock) {
            this.iPutGetBlock = iPutGetBlock;
        }

        @Override
        public void run() {
            super.run();

            while(!Thread.currentThread().isInterrupted()){
                try {
                    String msg = iPutGetBlock.getThread();
                    System.out.println("消費="+msg);
                } catch (InterruptedException e) {
                    System.out.println("被中斷!");
                    break;
                }
            }
        }
    }

    public static void main(String[] args) {
//        IPutGetBlock waitNotifyBlock = new WaitNotifyBlock(5);
//        IPutGetBlock waitNotifyBlock = new SemphoreBlock<>(5);
        IPutGetBlock waitNotifyBlock = new LockConditionBlock(5);
        new PutThread(waitNotifyBlock).start();
        new TaskThread(waitNotifyBlock).start();
        new TaskThread(waitNotifyBlock).start();

    }

}

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