8.并发编程--多线程通信-wait-notify-模拟Queue
并发编程--多线程通信-wait-notify-模拟Queue
1. BlockingQueue
顾名思义,首先是一个队列,其次支持阻塞的机制;阻塞放入和获取队列中的数据。
如何实现这样一个队列:
要实现比如LinkedBlockQueue 下面两个简单的方法 put和take
put(Object obj):把一个Object放入到BlockingQueue里:如果BlockingQueue没有空间,则调用此方法的线程被阻塞,直到BlockingQueue里面有空间再继续;
take():获取BlockingQueue队里中排在首位的数据,如果BlockingQueue没有数据,为空,或此方法阻塞,直到BlockingQueue有新的数据进入;
示例:
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; public class MyQueue { //1 需要一个承装元素的集合
private LinkedList<Object> list = new LinkedList<Object>(); //2 需要一个计数器
private AtomicInteger count = new AtomicInteger(0); //3 需要制定上限和下限
private final int minSize = 0; private final int maxSize ; //4 构造方法
public MyQueue(int size){
this.maxSize = size;
} //5 初始化一个对象 用于加锁
private final Object lock = new Object(); //put(anObject): 把anObject加到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的线程被阻断,直到BlockingQueue里面有空间再继续.
public void put(Object obj){
synchronized (lock) {
while(count.get() == this.maxSize){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//1 加入元素
list.add(obj);
//2 计数器累加
count.incrementAndGet();
//3 通知另外一个线程(唤醒)
lock.notify();
System.out.println("新加入的元素为:" + obj);
}
} //take: 取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的数据被加入.
public Object take(){
Object ret = null;
synchronized (lock) {
while(count.get() == this.minSize){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//1 做移除元素操作
ret = list.removeFirst();
//2 计数器递减
count.decrementAndGet();
//3 唤醒另外一个线程
lock.notify();
}
return ret;
} public int getSize(){
return this.count.get();
} public static void main(String[] args) { final MyQueue mq = new MyQueue(5);
mq.put("a");
mq.put("b");
mq.put("c");
mq.put("d");
mq.put("e"); System.out.println("当前容器的长度:" + mq.getSize()); Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
mq.put("f");
mq.put("g");
}
},"t1"); t1.start(); Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
Object o1 = mq.take();
System.out.println("移除的元素为:" + o1);
Object o2 = mq.take();
System.out.println("移除的元素为:" + o2);
}
},"t2"); try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
} t2.start(); }
}
8.并发编程--多线程通信-wait-notify-模拟Queue的更多相关文章
- 7.并发编程--多线程通信-wait-notify
并发编程--多线程通信-wait-notify 多线程通信:线程通信的目的是为了能够让线程之间相互发送信号; 1. 多线程通信: 线程通信的目的是为了能够让线程之间相互发送信号.另外,线程通信还能够使 ...
- python并发编程&多线程(二)
前导理论知识见:python并发编程&多线程(一) 一 threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性 官网链 ...
- python并发编程&多线程(一)
本篇理论居多,实际操作见: python并发编程&多线程(二) 一 什么是线程 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程,一 ...
- python 并发编程 多线程 目录
线程理论 python 并发编程 多线程 开启线程的两种方式 python 并发编程 多线程与多进程的区别 python 并发编程 多线程 Thread对象的其他属性或方法 python 并发编程 多 ...
- [并发编程 - 多线程:信号量、死锁与递归锁、时间Event、定时器Timer、线程队列、GIL锁]
[并发编程 - 多线程:信号量.死锁与递归锁.时间Event.定时器Timer.线程队列.GIL锁] 信号量 信号量Semaphore:管理一个内置的计数器 每当调用acquire()时内置计数器-1 ...
- Python并发编程——多线程与协程
Pythpn并发编程--多线程与协程 目录 Pythpn并发编程--多线程与协程 1. 进程与线程 1.1 概念上 1.2 多进程与多线程--同时执行多个任务 2. 并发和并行 3. Python多线 ...
- wait , notify 模拟 Queue
package com.itdoc.multi.sync009; import java.util.LinkedList; import java.util.concurrent.TimeUnit; ...
- Android并发编程 多线程与锁
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,如果能给各位看官带来一丝启发或者帮助,那真是极好的. 前言 前一篇Android并发编程开篇呢,主要是简单介绍一下线程以及 ...
- Java并发编程(多线程)中的相关概念
众所周知,在Java的知识体系中,并发编程是非常重要的一环,也是面试中必问的题,一个好的Java程序员是必须对并发编程这块有所了解的. 并发必须知道的概念 在深入学习并发编程之前,我们需要了解几个基本 ...
随机推荐
- python 安装 colorama 控制台输出彩色文字
pip install colorama from colorama import Back,Fore,Style # 字体颜色print(Fore.LIGHTBLUE_EX,'HelloWorLd' ...
- D - 秋实大哥与快餐店
秋实大哥与快餐店 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit ...
- RabbitMQ入门教程(三):Hello World
原文:RabbitMQ入门教程(三):Hello World 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog. ...
- 【微信小程序】图片压缩-纯质量压缩,非长宽裁剪压缩
原理:利用canvas来实现,将图片绘制到canvas上,然后canvas转图片时,微信提供的一个方法wx.canvasToTempFilePath(Object object, Object t ...
- 从HTTP request的body中拿到JSON并反序列化为一个对象
import com.google.gson.Gson; import org.apache.struts2.ServletActionContext; import javax.servlet.Se ...
- 引用vector里的元素被删除后,引用会怎么样?
引用的定义不多说,直接看做变量的别名就可以了.有一天写着写着代码,突然想到,如果对vector里某个元素设置引用后,将这个元素从vector里删除会怎么样?我思考了下,认为那个元素会被删除,但是引用还 ...
- token和sign
前言 在app开放接口api的设计中,避免不了的就是安全性问题,因为大多数接口涉及到用户的个人信息以及一些敏感的数据,所以对这些接口需要进行身份的认证,那么这就需要用户提供一些信息,比如用户名密码等, ...
- 清北学堂北京大学吴耀轩神仙讲课day5摘要
今天讲图论 图是啥?(白纸上的符号?) 对于一个拥有n个顶点的无向连通图,它的边数一定多于n-1条.若从中选择n-1条边,使得无向图仍然连通,则由n个顶点及这 n-1条边(弧)组成的图被称为原无向图的 ...
- python实例31[列出目录下所有的文件到txt]
代码: (使用os.listdir) import os def ListFilesToTxt(dir,file,wildcard,recursion): exts = wildcard.sp ...
- 使用SpringBoot发邮件
SpringBoot中已有发邮件的工具包,只需要引用即可使用 1,pom引用 <dependency> <groupId>org.springframework.boot< ...