前阵子学习了多线程,现在进行总结一下,模拟队列。

  分析问题:

  (1)首先需要一个容器存放元素,这里用linkedList队列。

  (2)每次像容器中添加或删除元素的时候需要计数,所以这里需要一个计数器,这里用原子类的atomicInter实现。

  (3)需要三个方法,一个put()方法,向容器中推数据,一个take()方法,向容器中取数据,一个size()方法,返回当前容器的大小。

  实现代码如下:

public class MyQueue {
//队列
private volatile LinkedList<Object> linkedList=new LinkedList<Object>();
//队列最大数
private int maxSize;
//队列最小数
private int minSize=0;
//计数器
private AtomicInteger count=new AtomicInteger(0);
//创建锁
private Object lock=new Object();
//初始化队列大小
public MyQueue(int maxSize){
this.maxSize=maxSize;
}
//返回当前队列的大小
public int getSize(){
return count.get();
}
//向队列添加元素方法
public void put(Object obj){
synchronized(lock){
if(getSize()==maxSize){
System.out.println("线程进入put方法中,阻塞中...");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
linkedList.add(obj);
count.getAndIncrement();
System.out.println("向队列中添加元素:"+obj);
lock.notify();//当容器大小为minSize时,且线程进行take操作时,执行了wait方法,进入了阻塞状态,所以添加完数据应该唤醒线程,进行数据take操作
}
}
//向队列中取出元素
public Object take(){
Object temp="";
synchronized(lock){
if(getSize()==minSize){
System.out.println("线程进入take方法中,阻塞中...");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
temp=linkedList.removeFirst();
count.getAndDecrement();
System.out.println("被取出的元素为:"+temp);
lock.notify();//当容器大小为maxSize时,且线程进行put操作时,执行了wait方法,进入了阻塞状态,所以取完数据应该唤醒线程,进行数据put操作
}
return temp;
} public static void main(String []args){
//初始化容器
final MyQueue myQueue=new MyQueue(5);
myQueue.put("A");
myQueue.put("B");
myQueue.put("C");
myQueue.put("D");
myQueue.put("E");
Thread t1=new Thread(new Runnable() {
public void run() {
myQueue.put("F");
}
},"t1");
Thread t2=new Thread(new Runnable() {
public void run() {
myQueue.take();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"t2");
Thread t3=new Thread(new Runnable() {
public void run() {
myQueue.take();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"t3");
Thread t4=new Thread(new Runnable() {
public void run() {
myQueue.put("G");
}
},"t4");
t1.start();
t2.start();
t3.start();
t4.start();
}
}

  

多线程-模拟阻塞queue队列的更多相关文章

  1. Java多线程——可阻塞的队列BlockingQueue

    阻塞队列与Semaphore有些相似,但也不同,阻塞队列是一方存放数据,另一方释放数据,Semaphore通常则是由同一方设置和释放信号量. ArrayBlockingQueue 只有put方法和ta ...

  2. python threading模块使用 以及python多线程操作的实践(使用Queue队列模块)

    今天花了近乎一天的时间研究python关于多线程的问题,查看了大量源码 自己也实践了一个生产消费者模型,所以把一天的收获总结一下. 由于GIL(Global Interpreter Lock)锁的关系 ...

  3. Java多线程与并发库高级应用-可阻塞的队列

    ArrayBlockQueue 可阻塞的队列 > 队列包含固定长度的队列和不固定长度的队列. > ArrayBlockQueue > 看BlockingQueue类的帮助文档,其中有 ...

  4. 使用goroutine+channel和java多线程+queue队列的方式开发各有什么优缺点?

    我感觉很多项目使用java或者c的多线程库+线程安全的queue数据结构基本上可以实现goroutine+channel开发能达到的需求,所以请问一下为什么说golang更适合并发服务端的开发呢?使用 ...

  5. Python之路-python(Queue队列、进程、Gevent协程、Select\Poll\Epoll异步IO与事件驱动)

    一.进程: 1.语法 2.进程间通讯 3.进程池 二.Gevent协程 三.Select\Poll\Epoll异步IO与事件驱动 一.进程: 1.语法 简单的启动线程语法 def run(name): ...

  6. 8.12 day31 进程间通信 Queue队列使用 生产者消费者模型 线程理论 创建及对象属性方法 线程互斥锁 守护线程

    进程补充 进程通信 要想实现进程间通信,可以用管道或者队列 队列比管道更好用(队列自带管道和锁) 管道和队列的共同特点:数据只有一份,取完就没了 无法重复获取用一份数据 队列特点:先进先出 堆栈特点: ...

  7. Python中多线程的阻塞问题

    在使用Queue模块+多线程模拟生产者+消费者问题时,遇到了一个小问题,现在记录下来.供可能会遇到类似问题的初学者们参考. 该问题的完整参考代码如下.主要实现了以下的功能:在一个线程中,开启生产者模式 ...

  8. Java并发包源码学习系列:基于CAS非阻塞并发队列ConcurrentLinkedQueue源码解析

    目录 非阻塞并发队列ConcurrentLinkedQueue概述 结构组成 基本不变式 head的不变式与可变式 tail的不变式与可变式 offer操作 源码解析 图解offer操作 JDK1.6 ...

  9. atitit. java queue 队列体系and自定义基于数据库的队列总结o7t

    atitit. java queue 队列体系and自定义基于数据库的队列总结o7t 1. 阻塞队列和非阻塞队列 1 2. java.util.Queue接口, 1 3. ConcurrentLink ...

随机推荐

  1. 《从零开始学Swift》学习笔记(Day 58)—— Swift编码规范之变量或常量声明规范

    原创文章,欢迎转载.转载请注明:关东升的博客 声明是在声明变量.常量.属性.方法或函数和自定义类型时候需要遵守的规范. 首先变量或常量时每行声明变量或常量的数量推荐一行一个,因为这样以利于写注释.示例 ...

  2. Kubernetes之kubectl常用命令

    最近项目有用到Kubernetes作集群配置,所以学习下相关命令,记录下以备下次使用... kubectl help 显示具体的用法 kubectl controls the Kubernetes c ...

  3. getComputedStyle获取css属性与IE下的currentStyle获取到的值不同

    <!doctype html><html lang="en"> <head>  <meta charset="UTF-8&quo ...

  4. ALTER TABLE causes auto_increment resequencing, resulting in duplicate entry ’1′ for key

    当我用SQLyog尝试修改已有记录的mysql数据表的主键为自动增长时,报出以下错误 ALTER TABLE causes auto_increment resequencing, resulting ...

  5. CXF 框架

    1. 搭建服务端(查询天气) // 1. 引入cxf的 jar 包; // 2. 创建 SEI 接口, 需要加入注解: @WebService @WebService public interface ...

  6. Linux基础命令(二)

    作业一:1) 新建用户natasha,uid为1000,gid为555,备注信息为“master” groupadd -g 555 netasha useradd -u 1000 -g netasha ...

  7. TempData、ViewData和ViewBag异同

    Data ViewData ViewBag都可以用来保存数据. 它们之间的区别如下: TempData:保存在Session中,Controller每次执行请求的时候,会从Session中先获取Tem ...

  8. 解锁Opera浏览器新姿势:【Surf The Internet In Right Ways】

    下载Opera浏览器 官网下载:https://www.opera.com/zh-cn 更改PC系统区域 我的本子是win10,其他系统未测. 进入: 设置 → 区域和语言 将国家或地区设置为:中国台 ...

  9. 为什么JSP的内置对象不需要声明

    本文将通过对一个JSP运行过程的剖析,深入JSP运行的内幕,并从全新的视角阐述一些JSP中的技术要点. HelloWorld.jsp 我们以Tomcat 4.1.17服务器为例,来看看最简单的Hell ...

  10. .tomcat 管理 给tomcat设置用户名和密码登录

    如果点击红色框框 出现403以下错误 看这个帖子可以解决 tomcat访问管理页面出现:403 Access Denied 解决方法 tomca管理 测试功能,生产环境不要用. Tomcat管理功能用 ...