当前位置: 首页 > news >正文

多线程—阻塞队列的练习

想要实现的效果:对于一个动态数组,添加两个线程,一个线程负责添加数据,一个线程负责移除数据,最终使得该动态数组动态平衡保持在20这个长度

要求:
添加数据:如果满了就阻塞等待–也就是说当达到20这个大小的时候,再加会加不进去。线程会陷入堵塞,只有等到大小达到20以下的时候才会执行add()操作
移除数据:如果空了就阻塞等待–也就是说当达到0这个大小的时候,再减会减不下去。线程会陷入堵塞,只有等到大小达到0以上的时候才会执行remove()操作
这里就先使用add()/remove()方法
表现第一点:先加到20,加到20之后,输出堵塞,然后等到减了一个元素之后,再运行添加操作并输出
表现第二点:先减到0,输出”堵塞“,然后等到加了一个元素之后,再运行删除操作并输出

(一)编写一个Main类:

package Test.MyArrayBlockinigQueue;import java.util.ArrayList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class Main {static ArrayList<Integer> arrBQ = new ArrayList<>();static Lock lock = new ReentrantLock();static Condition con = lock.newCondition();public static void main(String[] args) {AddTh add = new AddTh();RemoveTh remove = new RemoveTh();Thread addTh = new Thread(add);Thread removeTh = new Thread(remove);//演示减的操作就先增加到20,然后把增加操作延时一会,先运行移除操作for(int i = 0; i < 20 ; i ++){arrBQ.add(1);}//为什么当addTh里面每次循环如果不睡一会,就会在输出平台中出现断断续续的字迹try {Thread.sleep(200);} catch (InterruptedException e) {throw new RuntimeException(e);}removeTh.start();addTh.start();}
}

(二)编写一个添加的线程类:

package Test.MyArrayBlockinigQueue;public class AddTh implements Runnable{@Overridepublic void run() {//添加数据直到长度为20之后堵塞while(true){try {Thread.sleep(200);} catch (InterruptedException e) {throw new RuntimeException(e);}Main.lock.lock();try {Main.arrBQ.add(1);//长度大于等于20的时候陷入阻塞if (Main.arrBQ.size() >= 20) {System.out.println("要增,但此时长度为:" + Main.arrBQ.size() + ",陷入阻塞");Main.con.await();//长度小于20的时候继续加}else{System.out.println("要增,因为此时长度为:" + Main.arrBQ.size() + ",不再堵塞");Main.con.signal();}} catch (InterruptedException e) {throw new RuntimeException(e);} finally {Main.lock.unlock();}}}
}

(三)编写一个删除的线程类:

package Test.MyArrayBlockinigQueue;public class RemoveTh implements Runnable{@Overridepublic void run() {//添加数据直到长度为20之后堵塞while(true){//演示“增加”的阻塞就把减的操作延后一会
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }Main.lock.lock();try {Main.arrBQ.removeLast();//长度=0的时候陷入阻塞if (Main.arrBQ.isEmpty()) {System.out.println("要减,但此时长度为:" + Main.arrBQ.size() + ",陷入阻塞");Main.con.await();//长度大于0的时候继续减}else{System.out.println("要减,因为此时长度为:" + Main.arrBQ.size() + ",所以不再堵塞");Main.con.signal();}} catch (InterruptedException e) {throw new RuntimeException(e);} finally {Main.lock.unlock();}}}
}
注意:
1.如果要展示添加这个操作的阻塞情况,那么就需要把减的操作延后,因此需要在减的线程中设立睡眠时间,并且把加线程和主线程的睡眠和添加操作注释
2.如果要展示添加这个操作的阻塞情况,那么就需要在主函数中提前把数组加好,然后在加的线程中设立睡眠时间,并把减线程中的睡眠操作注释

实现效果:

1.添加阻塞:
在这里插入图片描述
2.删除阻塞:
在这里插入图片描述

——————————————————————————————————————————————————————————————————————————————————————————————————————(√)

进阶效果:创建一个仿ArrayBlockingQueue的动态数组,本身的put()/take()方法就具备了这样的特性

要求:
添加数据:如果满了就阻塞等待
移除数据:如果空了就阻塞等待
按照要求编写一个阻塞数组:

package Test.MyArrayBlockinigQueue;import com.sun.security.jgss.GSSUtil;import java.util.ArrayList;public class MyArrayBlockingQueue<E> {int length;ArrayList<E> arrBQ = new ArrayList<>();public MyArrayBlockingQueue(int length){this.length = length;}public void add(E i){Main.lock.lock();try {if (arrBQ.size() < length) {arrBQ.add(i);System.out.println("此时不满足20,可以加");Main.con.signal();} else {System.out.println("数组已满20");Main.con.await();}} catch (InterruptedException e) {throw new RuntimeException(e);} finally {Main.lock.unlock();}}public void removeLast(){Main.lock.lock();try{//回去进一步思考逻辑if(arrBQ.isEmpty()) {System.out.println("删不下去了,因为此时长度为0");Main.con.await();}else {System.out.println("可以删,因为此时有数据");arrBQ.removeLast();Main.con.signal();}} catch (InterruptedException e) {throw new RuntimeException(e);} finally {Main.lock.unlock();}}
}

(1)添加数据的阻塞情况的代码:

此时编写一个测试类:

package Test.MyArrayBlockinigQueue;public class Test {public static void main(String[] args) {MyArrayBlockingQueue<Integer> myArrBQ = new MyArrayBlockingQueue<>();for(int i = 0 ; i < 30 ; i++){myArrBQ.add(i);}}
}

效果如下:
在这里插入图片描述
(2)删除数据的阻塞队列的代码:
在原测试类中修改成:

package Test.MyArrayBlockinigQueue;import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;public class Test {public static void main(String[] args) {MyArrayBlockingQueue<Integer> myArrBQ = new MyArrayBlockingQueue<>(20);for(int i = 0 ; i < 20 ; i++){myArrBQ.add(i);}for(int i = 0 ; i < 30 ; i++){myArrBQ.removeLast();}}
}

实现效果如下:
在这里插入图片描述
至此,一个简单的阻塞队列实现。

http://www.dtcms.com/a/431947.html

相关文章:

  • C#基础10-结构体和枚举
  • 网站建设 福田东莞推广系统怎么做
  • 怎么做免费域名网站wordpress 图片库
  • 全网营销公司洛阳seo网络推广
  • git知识点
  • 制作网站要钱吗oppo开放平台
  • AI 伦理困局:参与式治理如何破解技术狂飙
  • 广州新际网站建设公司怎么样大连本地网
  • 【算法训练营Day27】动态规划part3
  • 网站后台管理系统软件开发一款app成本
  • 衡阳网站建设专家今天的特大新闻有哪些
  • 电子政务网站建设西安网站建设电话
  • 论文解读:GRAPHEVAL: A LIGHTWEIGHT GRAPH-BASED LLM FRAMEWORK FOR IDEA EVALUATION
  • 门业网站 模板it运维工程师工作内容
  • 河北省住房和城乡建设厅网站打不开学做网站论坛教程下载
  • Java 异常体系:从 Throwable 根类到自定义异常,一篇理清所有分类与逻辑
  • 仿5173网站汕尾旅游攻略app跳转网站
  • memory_profiler各个参数都是什么意思?
  • 网站开发技术简介dwsynology建设网站
  • p2p网站建设框架如何在google上免费推广
  • win7 win10 win11安装IE11浏览器
  • 深度学习池化(Pooling)的进阶应用与优化策略
  • 家庭宽带 做网站wordpress登陆后返回
  • 松岗网站的建设sasaki景观设计公司官网
  • 关于win11的Microsoft To Pdf打印机修改端口后无法再刷新显示于设备界面的问题
  • 深圳市网站建设外包公司排名某个网站做拍卖预展的好处
  • 苏州做网站公司认定苏州聚尚网络创新创意产品设计作品
  • AOI检测在半导体制造领域有哪些主要应用
  • 含山建设局网站支持快钱支付的网站
  • Win环境下包管理工具