如何自己实现一个BlockingQueue

1、synchronized模式

线程请求数据

@AllArgsConstructor
@Getter
public class Request {
    private final String name;

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

线程队列

public class RequestQueue {
    private final Queue<Request> queue = new LinkedList<>();
    public synchronized Request getRequest() {
        while (queue.peek() == null) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return queue.remove();
    }
    public synchronized void putRequest(Request request) {
        queue.offer(request);
        notifyAll();
    }
}

数据插入线程

@AllArgsConstructor
public class ClientThread implements Runnable {
    private final Random random;
    private final RequestQueue requestQueue;
    @Override
    public void run() {
        for (int i = 0;i < 10000;i++) {
            Request request = new Request("No." + i);
            System.out.println(Thread.currentThread().getName() + " Requests " + request);
            requestQueue.putRequest(request);
            try {
                Thread.sleep(random.nextInt(1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

数据取出线程

@AllArgsConstructor
public class ServerThread implements Runnable {
    private final Random random;
    private final RequestQueue requestQueue;
    @Override
    public void run() {
        for (int i = 0;i < 10000;i++) {
            Request request = requestQueue.getRequest();
            System.out.println(Thread.currentThread().getName() + " handles " + request);
            try {
                Thread.sleep(random.nextInt(1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

主方法

public class Main {
    public static void main(String[] args) {
        RequestQueue requestQueue = new RequestQueue();
        new Thread(new ClientThread(new Random(3141592L),requestQueue)).start();
        new Thread(new ServerThread(new Random(6535897L),requestQueue)).start();
    }
}

运行结果:

Thread-0 Requests [ Request No.0 ]
Thread-1 handles [ Request No.0 ]
Thread-0 Requests [ Request No.1 ]
Thread-0 Requests [ Request No.2 ]
Thread-1 handles [ Request No.1 ]
Thread-1 handles [ Request No.2 ]
Thread-0 Requests [ Request No.3 ]
Thread-1 handles [ Request No.3 ]
Thread-0 Requests [ Request No.4 ]
Thread-1 handles [ Request No.4 ]
Thread-0 Requests [ Request No.5 ]
Thread-0 Requests [ Request No.6 ]
Thread-1 handles [ Request No.5 ]

......

2、lock模式

唯一不同的是线程队列,其他同synchronized模式

public class RequestQueue {
    private final Queue<Request> queue = new LinkedList<>();
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    public  Request getRequest() {
        try {
            lock.lock();
            while (queue.peek() == null) {
                try {
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return queue.remove();
        } finally {
            lock.unlock();
        }
    }
    public void putRequest(Request request) {
        try {
            lock.lock();
            queue.offer(request);
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }
}

转载于:https://my.oschina.net/u/3768341/blog/3006596

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值