多线程-07-算法面试题--02--手写生产者消费者

设计一个有界阻塞队列:

(1)多线程写入队列,当队列满时不能再写入数据;

(2)单线程读取数据,当队列为空时不能读取数据;

(3)读取超过一定时长则运行结束。

一、Synchronized锁实现

package com.fuping3.proandcon;

import java.util.LinkedList;

public class ListQueue{
    private LinkedList<String> list=new LinkedList<String>();
    private volatile int cap=0;

    public ListQueue(int cap){
        this.cap=cap;
    }


    public void entraList(String str){

        synchronized (list){
            while(list.size()>=cap){
                System.out.println(Thread.currentThread().getName()+"阻塞");
                try {
                    list.wait();
                } catch (InterruptedException e) {
                    System.out.println(Thread.currentThread().getName()+"中断");
                    e.printStackTrace();
                }
            }

            list.addFirst(str);
            System.out.println(Thread.currentThread().getName()+"放入数据:"+str);
            list.notifyAll();
        }

    }
    public void popList(){
        String str="";
        boolean breakFlag=false;
        long now=System.currentTimeMillis();
        synchronized (list){
            while(list.isEmpty()){
                long end=System.currentTimeMillis();
                System.out.println(Thread.currentThread().getName()+"阻塞");
                try {
                    list.wait(1000*5);
                    if(end-now>1000){
                        breakFlag=true;
                        break;
                    }
                } catch (InterruptedException e) {
                    System.out.println(Thread.currentThread().getName()+"中断");
                    e.printStackTrace();
                }
            }
            if(!breakFlag){
                str=list.removeLast();
                System.out.println(Thread.currentThread().getName()+"消费数据:"+str);
                list.notifyAll();
            }

        }

    }
}

二、Lock锁实现

package com.fuping3.proandcon;

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

public class ListQueueWithAwait{
    ReentrantLock lock=new ReentrantLock();
    Condition c=lock.newCondition();
    private LinkedList<String> list=new LinkedList<String>();
    private volatile int cap=0;

    public ListQueueWithAwait(int cap){
        this.cap=cap;
    }

    public void entraList(String str){
        lock.lock();
        try {
            while(list.size()>=cap){
                System.out.println(Thread.currentThread().getName()+"阻塞");
                try {
                    c.await();
                } catch (InterruptedException e) {
                    System.out.println(Thread.currentThread().getName()+"中断");
                    e.printStackTrace();
                }
            }
            list.addFirst(str);
            System.out.println(Thread.currentThread().getName()+"放入数据:"+str);
            c.signalAll();
        }finally {
            lock.unlock();
        }
    }


    public void popList(){
        String str="";
        boolean breakFlag=false;
        long now=System.currentTimeMillis();
        lock.lock();
        try{
            while(list.isEmpty()){
                long end=System.currentTimeMillis();
                System.out.println(Thread.currentThread().getName()+"阻塞");
                try {
                    c.await(1000*5, TimeUnit.MILLISECONDS);
                    if(end-now>1000){
                        breakFlag=true;
                        break;
                    }
                } catch (InterruptedException e) {
                    System.out.println(Thread.currentThread().getName()+"中断");
                    e.printStackTrace();
                }
            }
            if(!breakFlag){
                str=list.removeLast();
                System.out.println(Thread.currentThread().getName()+"消费数据:"+str);
                c.signalAll();
            }
        }finally {
            lock.unlock();
        }

    }
}

三、测试代码

package com.fuping3.proandcon;

public class ProducerAndConsumer {
    private static Thread t1,t2;
    public static void main(String[] args) {
        //ListQueue list=new ListQueue(5);
        ListQueueWithAwait list=new ListQueueWithAwait(5);
        new Thread(()->{
            int i=1;
            while(i<=5){
                list.entraList("message"+i);
                i++;
            }
        },"p1").start();        new Thread(()->{
            int i=1;
            while(i<=5){
                list.entraList("message"+i);
                i++;
            }
        },"p2").start();
        new Thread(()->{
            int i=1;
            while(i<=5){
                list.entraList("message"+i);
                i++;
            }
        },"p3").start();
        new Thread(()->{
            int i=1;
            while(i<=16){
                list.popList();
                i++;
            }
        },"c1").start();
    }

}

四、运行结果

p1放入数据:message1
p1放入数据:message2
p1放入数据:message3
p1放入数据:message4
p1放入数据:message5
p2阻塞
p3阻塞
c1消费数据:message1
c1消费数据:message2
c1消费数据:message3
c1消费数据:message4
c1消费数据:message5
c1阻塞
p2放入数据:message1
p2放入数据:message2
p2放入数据:message3
p2放入数据:message4
p2放入数据:message5
p3阻塞
c1消费数据:message1
c1消费数据:message2
c1消费数据:message3
c1消费数据:message4
c1消费数据:message5
c1阻塞
p3放入数据:message1
p3放入数据:message2
p3放入数据:message3
p3放入数据:message4
p3放入数据:message5
c1消费数据:message1
c1消费数据:message2
c1消费数据:message3
c1消费数据:message4
c1消费数据:message5
c1阻塞
c1阻塞

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值