阻塞队列(多线程)

阻塞队列是带有阻塞功能且线程安全的队列.(即,队列为空,尝试出队列,出队列操作就会阻塞等待一直阻塞到队列不为空为止,队列为满,入队操作就会阻塞等待一直阻塞到队列不满为止.) 阻塞队列的作用之一就是可以实现生产者消费者模型,有两方面的作用1.能够让程序解耦合 2.能够实现"削峰填谷".

首先使用标准库提供的阻塞队列.

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Demo1 {
    public static void main(String[] args){
        BlockingQueue<Integer> queue=new ArrayBlockingQueue<>(10);
        //消费者
        //put带有阻塞功能的入队列  take带有阻塞功能的出队列
        Thread t1=new Thread(()->{
            while(true) {
                int value;
                try {
                    value = queue.take();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("消费的:" + value);

            }
        });
        Thread t2=new Thread(()-> {
            int count=1;
            while (true) {
                try {
                    queue.put(count);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("生产的:"+count);
                count++;
            }
        });
        t1.start();
        t2.start();
    }
}
//由于对生产和消费没有限制虽然限制了队列的大小是10,所以没有体现出阻塞功能.

import java.sql.SQLOutput;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Demo2 {
    public static void main(String[] args){
        BlockingQueue<Integer> queue=new ArrayBlockingQueue<>(10);
        //生产者
        Thread t1=new Thread(()->{
            int count=1;
            while(true){
                try {
                    queue.put(count);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("生产者:"+count);
                count++;
            }
            //如果对消费者的速度进行限制,那么会使阻塞队列满

        });
        //消费者
        Thread t2=new Thread(()->{
            int value;
            while(true){
                try {
                    value=queue.take();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("消费者:"+value);
            }
        });
        //这里消费者是一秒钟消费一次,因此在进行出队列的时候会发生阻塞
        //且队列中只有10个元素.
        t1.start();
        t2.start();
    }
}

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Demo3 {
    public static void main(String[] args){
        BlockingQueue<Integer> queue=new ArrayBlockingQueue<>(10);
        Thread t1=new Thread(()->{
            int count=1;
           while(true) {
               try {
                   queue.put(count);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               System.out.println("生产者:"+ count);
               count++;
           }
        });
        Thread t2=new Thread(()->{
            int value;
            while(true){
                try {
                    value=queue.take();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("消费者:"+value);
            }
        });
        //这一次是没有对生产者进行限制,因此消费者的节奏会跟着生产者.
        t1.start();
        t2.start();
    }
}

接下来自己实现一个带有阻塞功能的队列.

//自己实现阻塞队列
class MyblockingQueue{
    //自己实现阻塞队列
    //设置一个队列是存储整形的
    private int[] elems=null;
    //[head,tail)
    //head是头结点,tail是尾结点
    //开始的时候,头结点和尾结点都是0,size也是0
    private int head=0;
    private int tail=0;
    private int size=0;
    //构造方法
    public MyblockingQueue(int capacity){
        elems=new int[capacity];
    }
    //下面写入队列操作
    void put(int elem) throws InterruptedException {
        //首先要判断队列是否满
        synchronized(this) {
            while (size >= elems.length) {
                this.wait();
                //如果队列满了就要进行阻塞操作
                //一定要进行返回等待,等待出队列操作的执行
                return;
            }
            //队列没有满入队列时
            //尾结点指向的空间没有存储元素
            elems[tail] = elem;
            tail++;
            if (tail >= elems.length) {
                tail = 0;
                //到达了队列的末尾就要回到开头
            }
            size++;
            this.notify();
        }
    }
  //出队列操作
    int take() throws InterruptedException {
        synchronized(this) {
            //还是要先判断队列是否是空,如果为空,就要阻塞等待
            while (size == 0) {
                this.wait();
                return -99999;
            }
            //出队列操作
            int result = elems[head];
            head++;
            if (head >= elems.length) {
                head = 0;
            }
            size--;
            this.notify();
            return result;
        }
    }
}
public class Demo2 {
    public static void main(String[] args) {
        MyblockingQueue tt=new MyblockingQueue(10);
        Thread t1=new Thread(()->{
            int count=0;
           while(true){
               try {
                   tt.put(count);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               System.out.println("生产者: "+count);
               count++;
           }
        });
        Thread t2=new Thread(()->{
           int value;
           while(true){
               try {
                   value=tt.take();
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               System.out.println("消费者: "+value);
           }
        });
        t1.start();
        t2.start();
    }

}
相关推荐
wzg20164 分钟前
python装饰器
开发语言·python
十二测试录4 分钟前
Python基础——字符串
开发语言·经验分享·python·程序人生·职场发展
爬菜8 分钟前
java简单题目练习
java
bufanjun0019 分钟前
JUC并发工具---ThreadLocal
java·jvm·面试·并发·并发基础
南宫生19 分钟前
力扣-图论-70【算法学习day.70】
java·学习·算法·leetcode·图论
zfj32119 分钟前
java日志框架:slf4j、jul(java.util.logging)、 log4j、 logback
java·log4j·logback·java日志框架·slf4j·jul
程序猿阿伟26 分钟前
《探索 Apache Spark MLlib 与 Java 结合的卓越之道》
java·spark-ml·apache
一條狗31 分钟前
隨筆 20241224 ts寫入excel表
开发语言·前端·typescript
NY634 分钟前
mysql运维篇笔记——日志,主从复制,分库分表,读写分离
数据库·sql
向阳121835 分钟前
sentinel来源访问控制(黑白名单)
java·sentinel