阻塞队列

1.阻塞队列

​ (1)什么是阻塞队列?

​ 可以在多线程环境下安全使用,并且支持阻塞、等待的队列。

​ 注:阻塞、等待指的是当队列满的时候会阻塞生产者线程,直到队列不满;

​ 当队列为空的时候会阻塞消费者线程,直到队列不空。

在这里插入图片描述

(2)阻塞队列的使用

​ BlockingQueue接口,LinkedBlockingQueue是该接口的一个实现类。

​ 练习1:

​ 写一个生产者消费者模型,要求如下:

​ a.阻塞队列只能存放10个元素

​ b.生产者每隔1秒向阻塞队列中添加一个随机数,消费者每隔20秒从阻塞队列中获取

​ 随机数然后在控制台输出。

​ 参考代码:

/**
 * 生产者
 */
public class Producer implements  Runnable{
    private BlockingQueue<Integer> bq;

    public Producer(BlockingQueue bq) {
        this.bq = bq;
    }

    @Override
    public void run() {
        Random rd = new Random();
        while (true){
            int number = rd.nextInt(1000);
            System.out.println("生产者线程向阻塞队列中写入一个随机数:"
                    + number);
            try {
                bq.put(number);
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

/**
 * 消费者
 */
public class Consumer implements  Runnable{
    private BlockingQueue<Integer> bq;

    public Consumer(BlockingQueue bq) {
        this.bq = bq;
    }

    @Override
    public void run() {
        while (true){
            try {
                int number = bq.take();
                System.out.println("消费者线程从阻塞队列中获取一个随机数:"+ number);
                Thread.sleep(20000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class Test {
    public static void main(String[] args) {
        BlockingQueue<Integer> bq =
                new LinkedBlockingQueue<>(10);
        Producer p = new Producer(bq);
        Consumer c = new Consumer(bq);
        new Thread(p).start();
        new Thread(c).start();
    }
}

练习2: 写一个日志工具类

在这里插入图片描述

参考代码:

/**
 * 记日志的工具类
 */
public class Logger {
    //bq用于存放日志信息
    private BlockingQueue<String> bq;
    //out指向日志文件
    private PrintWriter out;

    /**
     *  open方法为记日志做一些准备工作。
     *
     */
    public void open() throws FileNotFoundException {
        //1.创建一个阻塞队列
        bq = new LinkedBlockingQueue<>(1000);
        //2. 打开日志文件
        out = new PrintWriter("logger.txt");
        //3. 启动记日志的线程
        Thread t = new Thread(){
            @Override
            public void run() {
               while(true){
                   try {
                       System.out.println("从阻塞队列中读取日志信息...");
                       //从阻塞队列中读取日志信息
                       String info = bq.take();
                       //将日志信息写到日志文件里面
                       out.println(info);
                       System.out.println("将日志信息:" + info + "写入日志文件了");
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
            }
        };
        //启动记日志的线程
        t.start();

    }

    /**
     * 记日志方法
     * @param info 日志信息
     */
    public void log(String info){
        try {
            System.out.println("开始向阻塞队列中写入日志信息...");
            //将日志信息写到阻塞队列里面就可以了
            bq.put(info);
            System.out.println("日志信息“ + info + ”写入阻塞队列完毕");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭日志文件
     */
    public void close(){
        if(out != null){
            out.close();
        }
    }
}
public class LoggerTest {
    public static void main(String[] args) throws FileNotFoundException {
        Logger logger = new Logger();
        logger.open();
        logger.log("Hello Kitty");
        logger.log("balabala");
        logger.log("hehehe");
        logger.log("heihei");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        logger.close();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值