深圳网站建设民治大道,江西省城市建设档案馆网站,Wordpress 缓存策略,龙游网站制作文章目录 1. 什么是堵塞队列#xff1f;2. 堵塞队列的方法3. 生产者消费者模型4. 自己实现堵塞队列 1. 什么是堵塞队列#xff1f; 堵塞队列也是队列#xff0c;故遵循先进先出的原则。但堵塞队列是一种线程安全的数据结构#xff0c;可以避免线程安全问题#xff0c;当队… 文章目录 1. 什么是堵塞队列2. 堵塞队列的方法3. 生产者消费者模型4. 自己实现堵塞队列 1. 什么是堵塞队列 堵塞队列也是队列故遵循先进先出的原则。但堵塞队列是一种线程安全的数据结构可以避免线程安全问题当队列为空时继续出队列会发生堵塞直至其他线程有元素进队列。当队列满时继续入队列会堵塞直至其他线程有元素出队列。 生产者消费者模型就是最经典的堵塞队列模型之一。 2. 堵塞队列的方法 Java标准库里含有堵塞队列我们使用时可以直接使用标准库即可。 BlockingQueue是个接口真正实现的类是LinkedBlockingQueue。put方法入队列take方法出队列具有堵塞性。peekofferpoll等方法也可以使用但是不具有堵塞性。
BlockingQueueInteger queue new LinkedBlockingQueue();
queue.put();
queue.take();3. 生产者消费者模型 这是一个常见的并发编程模型用于协调生产者和消费者之间的工作在这个模型中一个线程负责生产元素一个线程负责消费元素。 它也是一个堵塞队列 所以具有堵塞队列的特性。 public class Test {public static void main(String[] args) {BlockingQueueInteger queue new LinkedBlockingQueue();//t1线程负责生产元素Thread t1 new Thread(() - {try{Random random new Random();while (true){int i random.nextInt();System.out.println(生产元素: i);queue.put(i);Thread.sleep(1000);}}catch (InterruptedException e){e.printStackTrace();}});//t2负责消费元素Thread t2 new Thread(() - {try {while(true){int i queue.take();System.out.println(消费元素: i);}} catch (InterruptedException e) {e.printStackTrace();}});t1.start();t2.start();}
}运行结果
4. 自己实现堵塞队列 自己实现堵塞队列需要满足 通过循环队列来实现使用synchronized实现加锁进行同步put 插入元素的时候, 判定如果队列满了, 就进行 wait. (注意, 要在循环中进行 wait. 被唤醒时不一定队列就不满了, 因为同时可能是唤醒了多个线程)take 取出元素的时候, 判定如果队列为空, 就进行 wait. (也是循环 wait) class BlockingQueue{//定义一个数组private int[] arr;//数组中元素个数private int size 0;//记录数组头的位置private int read 0;//记录尾的位置private int tail 0;//锁Object lock new Object();//构造方法确定数组大小public BlockingQueue(int i){arr new int[i];}//入队列public void put(int value){try{//加锁保证线程安全synchronized (lock){//使用while不要使用if否则notifyAll时所有等待线程都被唤醒造成线程安全while(arr.length size){lock.wait();}arr[tail] value;//循环队列tail (tail 1) % arr.length;//添加一个元素size加一次size;//唤醒所有线程lock.notifyAll();}}catch (InterruptedException e){e.printStackTrace();}}public int take() {//返回值不能写在try里面int value 0;try {//上锁synchronized (lock) {//队列为0等待使用whilewhile (size 0) {lock.wait();}//赋返回值value arr[read];//循环read (read 1) % arr.length;//出队列一个减一个size--;//唤醒lock.notifyAll();}} catch (InterruptedException e) {e.printStackTrace();}//返回值return value;}}
public class Test4 {public static void main(String[] args) throws InterruptedException {BlockingQueue queue new BlockingQueue(10);Thread t1 new Thread(() - {try{Random random new Random();while (true){int value random.nextInt(100);System.out.println(生产元素: value);queue.put(value);Thread.sleep(100);}}catch (InterruptedException e){e.printStackTrace();}});//t2负责消费元素Thread t2 new Thread(() - {while(true){int value queue.take();System.out.println(消费元素: value);}});t1.start();Thread.sleep(2000);t2.start();}
}1 因为t2 未启动所以只能生产元素当生产10个元素后队列满了进入堵塞等待被唤醒 2 因为t1生产时每次都会休眠线程执行非常迅速所以队列一直出元素直到队列为空进入堵塞等待被唤醒 3生产一个元素消费一个元素。