ArrayBlockingQueue 阻塞队列和 Semaphore 信号灯的应用
- import java.util.concurrent.ArrayBlockingQueue;
- import java.util.concurrent.BlockingQueue;
- public class BlockingQueueTest {
- public static void main(String[] args) {
- final BlockingQueue queue = new ArrayBlockingQueue(3); //允许放三个数据的队列
- for (int i = 0; i < 2; i++) { //模拟两个线程
- new Thread() {
- public void run() {
- while (true) { //一直是true的话,就一直进来
- try {
- Thread.sleep((long) (Math.random() * 1000)); //Math.random() 返回小于1的随机数
- System.out.println(Thread.currentThread().getName() + "准备放数据!");
- queue.put(1); //放数据 当满了三个的时候就放不进去,就阻塞
- System.out.println(Thread.currentThread().getName() + "已经放了数据," +
- "队列目前有" + queue.size() + "个数据");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }.start();
- }
- new Thread() {
- public void run() {
- while (true) { //一直是true的话,就一直进来
- try {
- //将此处的睡眠时间分别改为100和1000,观察运行结果
- Thread.sleep(1000);
- System.out.println(Thread.currentThread().getName() + "准备取数据!");
- queue.take(); //拿走数据,没有数据取的话就在这里一直堵着
- System.out.println(Thread.currentThread().getName() + "已经取走数据," +
- "队列目前有" + queue.size() + "个数据");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }.start();
- }
- }
第一题:现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志,请在程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,程序只需要运行4秒即可打印完这些日志对象。原始代码如下:
- package read;
- public class Test {
- public static void main(String[] args){
- System.out.println("begin:"+(System.currentTimeMillis()/1000));
- /*模拟处理16行日志,下面的代码产生了16个日志对象,当前代码需要运行16秒才能打印完这些日志。
- 修改程序代码,开四个线程让这16个对象在4秒钟打完。
- */
- for(int i=0;i<16;i++){ //这行代码不能改动
- final String log = ""+(i+1);//这行代码不能改动
- {
- Test.parseLog(log);
- }
- }
- }
- //parseLog方法内部的代码不能改动
- public static void parseLog(String log){
- System.out.println(log+":"+(System.currentTimeMillis()/1000));
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
实现的代码:
- package read;
- import java.util.concurrent.ArrayBlockingQueue;
- import java.util.concurrent.BlockingQueue;
- public class Test {
- public static void main(String[] args) {
- //一开始new了四个线程,每个线程都在等待打印,等for循环队列获取数据之后,
- //每个线程都将数据打印出来
- //parseLog因为打印方法休眠了一秒,所以就实现了1秒打印出四条数据
- final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(16);
- for (int i = 0; i < 4; i++) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- while (true) {
- try {
- String log = queue.take();
- parseLog(log);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }).start();
- }
- System.out.println("begin:" + (System.currentTimeMillis() / 1000));
- /*模拟处理16行日志,下面的代码产生了16个日志对象,当前代码需要运行16秒才能打印完这些日志。
- 修改程序代码,开四个线程让这16个对象在4秒钟打完。
- */
- for (int i = 0; i < 16; i++) { //这行代码不能改动
- final String log = "" + (i + 1);//这行代码不能改动
- {
- try {
- queue.put(log);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- //Test.parseLog(log);
- }
- }
- }
- //parseLog方法内部的代码不能改动
- public static void parseLog(String log) {
- System.out.println(log + ":" + (System.currentTimeMillis() / 1000));
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
第二题:现成程序中的Test类中的代码在不断地产生数据,然后交给TestDo.doSome()方法去处理,就好像生产者在不断地产生数据,消费者在不断消费数据。请将程序改造成有10个线程来消费生成者产生的数据,这些消费者都调用TestDo.doSome()方法去进行处理,故每个消费者都需要一秒才能处理完,程序应保证这些消费者线程依次有序地消费数据,只有上一个消费者消费完后,下一个消费者才能消费数据,下一个消费者是谁都可以,但要保证这些消费者线程拿到的数据是有顺序的。原始代码如下:
- package queue;
- public class Test {
- public static void main(String[] args) {
- System.out.println("begin:"+(System.currentTimeMillis()/1000));
- for(int i=0;i<10;i++){ //这行不能改动
- String input = i+""; //这行不能改动
- String output = TestDo.doSome(input);
- System.out.println(Thread.currentThread().getName()+ ":" + output);
- }
- }
- }
- //不能改动此TestDo类
- class TestDo {
- public static String doSome(String input){
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- String output = input + ":"+ (System.currentTimeMillis() / 1000);
- return output;
- }
- }
实现的代码:
- package queue;
- import java.util.concurrent.Semaphore;
- import java.util.concurrent.SynchronousQueue;
- public class Test {
- public static void main(String[] args) {
- final Semaphore semaphore = new Semaphore(1);
- final SynchronousQueue<String> queue = new SynchronousQueue<String>();
- for (int i = 0; i < 10; i++) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- semaphore.acquire();
- String input = queue.take();
- String output = TestDo.doSome(input);
- System.out.println(Thread.currentThread().getName() + ":" + output);
- semaphore.release();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }).start();
- }
- System.out.println("begin:" + (System.currentTimeMillis() / 1000));
- for (int i = 0; i < 10; i++) { //这行不能改动
- String input = i + ""; //这行不能改动
- try {
- queue.put(input);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
- //不能改动此TestDo类
- class TestDo {
- public static String doSome(String input) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- String output = input + ":" + (System.currentTimeMillis() / 1000);
- return output;
- }
- }
ArrayBlockingQueue 阻塞队列和 Semaphore 信号灯的应用的更多相关文章
- Condition对象以及ArrayBlockingQueue阻塞队列的实现(使用Condition在队满时让生产者线程等待, 在队空时让消费者线程等待)
Condition对象 一).Condition的定义 Condition对象:与锁关联,协调多线程间的复杂协作. 获取与锁绑定的Condition对象: Lock lock = new Reentr ...
- ArrayBlockingQueue 阻塞队列 生产者 与消费者案例
package com.originalityTest; import java.net.UnknownHostException; import java.util.ArrayList; impor ...
- 10.并发包阻塞队列之ArrayBlockingQueue
上一节中对并发包中的非阻塞队列ConcurrentLinkedQueue的入队.出队做了一个简要的分析,本文将对并发包中的阻塞队列做一个简要分析. Java并发包中的阻塞队列一共7个,当然他们都是线程 ...
- 并发包阻塞队列之ArrayBlockingQueue
并发包阻塞队列之ArrayBlockingQueue jdk1.7.0_79 上一节中对并发包中的非阻塞队列ConcurrentLinkedQueue的入队.出队做了一个简要的分析,本文将对并发 ...
- BlockingQueue-线程的阻塞队列
BlockingQueue作为线程容器,可以为线程同步提供有力的保障,其主要用到的方法包括: add(E o); //将指定的元素添加到此队列中(如果立即可行),在成功时返回 true,其他情况则抛出 ...
- 并发库应用之十一 & 阻塞队列的应用
队列包含固定长度的队列和不固定长度的队列,队列的规则就是:先进先出.固定长度的队列往里放数据,如果放满了还要放,阻塞式队列就会等待,直到有数据取出,空出位置后才继续放:非阻塞式队列不能等待就只能报错了 ...
- JAVA可阻塞队列-ArrayBlockingQueue
在前面的的文章,写了一个带有缓冲区的队列,是用JAVA的Lock下的Condition实现的,但是JAVA类中提供了这项功能,就是ArrayBlockingQueue, ArrayBlockingQu ...
- Java并发之BlockingQueue 阻塞队列(ArrayBlockingQueue、LinkedBlockingQueue、DelayQueue、PriorityBlockingQueue、SynchronousQueue)
package com.thread.test.thread; import java.util.Random; import java.util.concurrent.*; /** * Create ...
- Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍
1.什么是阻塞队列? 所谓队列,遵循的是先进先出原则(FIFO),阻塞队列,即是数据共享时,A在写数据时,B想读同一数据,那么就将发生阻塞了. 看一下线程的四种状态,首先是新创建一个线程,然后,通过s ...
随机推荐
- Centos 6.5下的OPENJDK卸载和SUN的JDK安装、环境变量配置
不多说,直接上干货! 说明 图形界面安装,会自带有Centos6.5自带的OPRNJDK!!! *********************************自带的OPENJDK的卸载****** ...
- Flow类
JLS参考:https://docs.oracle.com/javase/specs/jls/se7/html/jls-16.html This pass implements dataflow an ...
- 机器学习--boosting家族之GBDT
本文就对Boosting家族中另一个重要的算法梯度提升树(Gradient Boosting Decison Tree, 以下简称GBDT)做一个总结.GBDT有很多简称,有GBT(Gradient ...
- springboot-5-整合jpa
######## ##springboot-parent.version: ## jdk 1.8 ## ####### 在整合jpa之前, 先说下mysql 步骤: 1), 在application. ...
- hadoop下安装mahout
安装hadoop 完成 安装mahout 首先下载mahout压缩文件apache-mahout-distribution-0.12.2.tar.gz 放到/home/hadoop/software- ...
- CSS3设置Table奇数行和偶数行样式
table:.myTable tr:nth-child(even){ //偶数行 background:#fff;}.myTable tr:nth-child(odd){ //奇数行 backgrou ...
- ionic中generate page后module.ts报错的解决办法
此问题出现在Ionic官方将版本从2.2升级到Ionic3以上之后, 在项目中generate page时,自动创建的module.ts就报错,如下: 解决办法如下: 1)将IonicModule替换 ...
- js判断用户是否离开当前页面
简介 VisibilityChange 事件:用于判断用户是否离开当前页面 Code // 页面的 visibility 属性可能返回三种状态 // prerender,visible 和 hidde ...
- PHP网站(Drupal7)响应过慢之“Wating(TTFB)时间过长”
直接上图: 这是Chrome浏览器自带的工具分析的.整个url请求的时间为2.59秒,最大的耗时在Wating(TTFB, Time To First Byte),消耗了2.59秒(应该是其他时间太短 ...
- sqlserver年月日转汉字大写
也是今天sql群里有人问,看起来这个问题挺简单,但是我不知道具体该怎么实现.百度了一把,找到一个高手贡献的答案,记一下. 参考链接 sql中转换中文日期 ------ 配合相关函数 ------ cr ...