1. import java.util.concurrent.ArrayBlockingQueue;
  2. import java.util.concurrent.BlockingQueue;
  3.  
  4. public class BlockingQueueTest {
  5. public static void main(String[] args) {
  6. final BlockingQueue queue = new ArrayBlockingQueue(3); //允许放三个数据的队列
  7.  
  8. for (int i = 0; i < 2; i++) { //模拟两个线程
  9. new Thread() {
  10. public void run() {
  11. while (true) { //一直是true的话,就一直进来
  12. try {
  13. Thread.sleep((long) (Math.random() * 1000)); //Math.random() 返回小于1的随机数
  14. System.out.println(Thread.currentThread().getName() + "准备放数据!");
  15. queue.put(1); //放数据 当满了三个的时候就放不进去,就阻塞
  16. System.out.println(Thread.currentThread().getName() + "已经放了数据," +
  17. "队列目前有" + queue.size() + "个数据");
  18. } catch (InterruptedException e) {
  19. e.printStackTrace();
  20. }
  21.  
  22. }
  23. }
  24.  
  25. }.start();
  26. }
  27.  
  28. new Thread() {
  29. public void run() {
  30. while (true) { //一直是true的话,就一直进来
  31. try {
  32. //将此处的睡眠时间分别改为100和1000,观察运行结果
  33. Thread.sleep(1000);
  34. System.out.println(Thread.currentThread().getName() + "准备取数据!");
  35. queue.take(); //拿走数据,没有数据取的话就在这里一直堵着
  36. System.out.println(Thread.currentThread().getName() + "已经取走数据," +
  37. "队列目前有" + queue.size() + "个数据");
  38. } catch (InterruptedException e) {
  39. e.printStackTrace();
  40. }
  41. }
  42. }
  43. }.start();
  44. }
  45. }

第一题:现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志,请在程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,程序只需要运行4秒即可打印完这些日志对象。原始代码如下:

  1. package read;
  2.  
  3. public class Test {
  4.  
  5. public static void main(String[] args){
  6.  
  7. System.out.println("begin:"+(System.currentTimeMillis()/1000));
  8. /*模拟处理16行日志,下面的代码产生了16个日志对象,当前代码需要运行16秒才能打印完这些日志。
  9. 修改程序代码,开四个线程让这16个对象在4秒钟打完。
  10. */
  11. for(int i=0;i<16;i++){ //这行代码不能改动
  12. final String log = ""+(i+1);//这行代码不能改动
  13. {
  14. Test.parseLog(log);
  15. }
  16. }
  17. }
  18.  
  19. //parseLog方法内部的代码不能改动
  20. public static void parseLog(String log){
  21. System.out.println(log+":"+(System.currentTimeMillis()/1000));
  22.  
  23. try {
  24. Thread.sleep(1000);
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. }
  28. }
  29.  
  30. }

实现的代码:

  1. package read;
  2.  
  3. import java.util.concurrent.ArrayBlockingQueue;
  4. import java.util.concurrent.BlockingQueue;
  5.  
  6. public class Test {
  7.  
  8. public static void main(String[] args) {
  9.  
  10. //一开始new了四个线程,每个线程都在等待打印,等for循环队列获取数据之后,
  11. //每个线程都将数据打印出来
  12. //parseLog因为打印方法休眠了一秒,所以就实现了1秒打印出四条数据
  13.  
  14. final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(16);
  15. for (int i = 0; i < 4; i++) {
  16. new Thread(new Runnable() {
  17. @Override
  18. public void run() {
  19. while (true) {
  20. try {
  21. String log = queue.take();
  22. parseLog(log);
  23. } catch (InterruptedException e) {
  24. // TODO Auto-generated catch block
  25. e.printStackTrace();
  26. }
  27. }
  28. }
  29.  
  30. }).start();
  31. }
  32.  
  33. System.out.println("begin:" + (System.currentTimeMillis() / 1000));
  34. /*模拟处理16行日志,下面的代码产生了16个日志对象,当前代码需要运行16秒才能打印完这些日志。
  35. 修改程序代码,开四个线程让这16个对象在4秒钟打完。
  36. */
  37. for (int i = 0; i < 16; i++) { //这行代码不能改动
  38. final String log = "" + (i + 1);//这行代码不能改动
  39. {
  40. try {
  41. queue.put(log);
  42. } catch (InterruptedException e) {
  43. // TODO Auto-generated catch block
  44. e.printStackTrace();
  45. }
  46. //Test.parseLog(log);
  47. }
  48. }
  49. }
  50.  
  51. //parseLog方法内部的代码不能改动
  52. public static void parseLog(String log) {
  53. System.out.println(log + ":" + (System.currentTimeMillis() / 1000));
  54.  
  55. try {
  56. Thread.sleep(1000);
  57. } catch (InterruptedException e) {
  58. e.printStackTrace();
  59. }
  60. }
  61.  
  62. }

第二题:现成程序中的Test类中的代码在不断地产生数据,然后交给TestDo.doSome()方法去处理,就好像生产者在不断地产生数据,消费者在不断消费数据。请将程序改造成有10个线程来消费生成者产生的数据,这些消费者都调用TestDo.doSome()方法去进行处理,故每个消费者都需要一秒才能处理完,程序应保证这些消费者线程依次有序地消费数据,只有上一个消费者消费完后,下一个消费者才能消费数据,下一个消费者是谁都可以,但要保证这些消费者线程拿到的数据是有顺序的。原始代码如下:

  1. package queue;
  2.  
  3. public class Test {
  4.  
  5. public static void main(String[] args) {
  6.  
  7. System.out.println("begin:"+(System.currentTimeMillis()/1000));
  8. for(int i=0;i<10;i++){ //这行不能改动
  9. String input = i+""; //这行不能改动
  10. String output = TestDo.doSome(input);
  11. System.out.println(Thread.currentThread().getName()+ ":" + output);
  12. }
  13. }
  14. }
  15.  
  16. //不能改动此TestDo类
  17. class TestDo {
  18. public static String doSome(String input){
  19.  
  20. try {
  21. Thread.sleep(1000);
  22. } catch (InterruptedException e) {
  23. e.printStackTrace();
  24. }
  25. String output = input + ":"+ (System.currentTimeMillis() / 1000);
  26. return output;
  27. }
  28. }

实现的代码:

  1. package queue;
  2.  
  3. import java.util.concurrent.Semaphore;
  4. import java.util.concurrent.SynchronousQueue;
  5.  
  6. public class Test {
  7.  
  8. public static void main(String[] args) {
  9. final Semaphore semaphore = new Semaphore(1);
  10. final SynchronousQueue<String> queue = new SynchronousQueue<String>();
  11. for (int i = 0; i < 10; i++) {
  12. new Thread(new Runnable() {
  13. @Override
  14. public void run() {
  15. try {
  16. semaphore.acquire();
  17. String input = queue.take();
  18. String output = TestDo.doSome(input);
  19. System.out.println(Thread.currentThread().getName() + ":" + output);
  20. semaphore.release();
  21. } catch (InterruptedException e) {
  22. // TODO Auto-generated catch block
  23. e.printStackTrace();
  24. }
  25. }
  26. }).start();
  27. }
  28.  
  29. System.out.println("begin:" + (System.currentTimeMillis() / 1000));
  30. for (int i = 0; i < 10; i++) { //这行不能改动
  31. String input = i + ""; //这行不能改动
  32. try {
  33. queue.put(input);
  34. } catch (InterruptedException e) {
  35. // TODO Auto-generated catch block
  36. e.printStackTrace();
  37. }
  38. }
  39. }
  40. }
  41.  
  42. //不能改动此TestDo类
  43. class TestDo {
  44. public static String doSome(String input) {
  45.  
  46. try {
  47. Thread.sleep(1000);
  48. } catch (InterruptedException e) {
  49. e.printStackTrace();
  50. }
  51. String output = input + ":" + (System.currentTimeMillis() / 1000);
  52. return output;
  53. }
  54. }

ArrayBlockingQueue 阻塞队列和 Semaphore 信号灯的应用的更多相关文章

  1. Condition对象以及ArrayBlockingQueue阻塞队列的实现(使用Condition在队满时让生产者线程等待, 在队空时让消费者线程等待)

    Condition对象 一).Condition的定义 Condition对象:与锁关联,协调多线程间的复杂协作. 获取与锁绑定的Condition对象: Lock lock = new Reentr ...

  2. ArrayBlockingQueue 阻塞队列 生产者 与消费者案例

    package com.originalityTest; import java.net.UnknownHostException; import java.util.ArrayList; impor ...

  3. 10.并发包阻塞队列之ArrayBlockingQueue

    上一节中对并发包中的非阻塞队列ConcurrentLinkedQueue的入队.出队做了一个简要的分析,本文将对并发包中的阻塞队列做一个简要分析. Java并发包中的阻塞队列一共7个,当然他们都是线程 ...

  4. 并发包阻塞队列之ArrayBlockingQueue

    并发包阻塞队列之ArrayBlockingQueue   jdk1.7.0_79  上一节中对并发包中的非阻塞队列ConcurrentLinkedQueue的入队.出队做了一个简要的分析,本文将对并发 ...

  5. BlockingQueue-线程的阻塞队列

    BlockingQueue作为线程容器,可以为线程同步提供有力的保障,其主要用到的方法包括: add(E o); //将指定的元素添加到此队列中(如果立即可行),在成功时返回 true,其他情况则抛出 ...

  6. 并发库应用之十一 & 阻塞队列的应用

    队列包含固定长度的队列和不固定长度的队列,队列的规则就是:先进先出.固定长度的队列往里放数据,如果放满了还要放,阻塞式队列就会等待,直到有数据取出,空出位置后才继续放:非阻塞式队列不能等待就只能报错了 ...

  7. JAVA可阻塞队列-ArrayBlockingQueue

    在前面的的文章,写了一个带有缓冲区的队列,是用JAVA的Lock下的Condition实现的,但是JAVA类中提供了这项功能,就是ArrayBlockingQueue, ArrayBlockingQu ...

  8. Java并发之BlockingQueue 阻塞队列(ArrayBlockingQueue、LinkedBlockingQueue、DelayQueue、PriorityBlockingQueue、SynchronousQueue)

    package com.thread.test.thread; import java.util.Random; import java.util.concurrent.*; /** * Create ...

  9. Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍

    1.什么是阻塞队列? 所谓队列,遵循的是先进先出原则(FIFO),阻塞队列,即是数据共享时,A在写数据时,B想读同一数据,那么就将发生阻塞了. 看一下线程的四种状态,首先是新创建一个线程,然后,通过s ...

随机推荐

  1. Centos 6.5下的OPENJDK卸载和SUN的JDK安装、环境变量配置

    不多说,直接上干货! 说明 图形界面安装,会自带有Centos6.5自带的OPRNJDK!!! *********************************自带的OPENJDK的卸载****** ...

  2. Flow类

    JLS参考:https://docs.oracle.com/javase/specs/jls/se7/html/jls-16.html This pass implements dataflow an ...

  3. 机器学习--boosting家族之GBDT

    本文就对Boosting家族中另一个重要的算法梯度提升树(Gradient Boosting Decison Tree, 以下简称GBDT)做一个总结.GBDT有很多简称,有GBT(Gradient ...

  4. springboot-5-整合jpa

    ######## ##springboot-parent.version: ## jdk 1.8 ## ####### 在整合jpa之前, 先说下mysql 步骤: 1), 在application. ...

  5. hadoop下安装mahout

    安装hadoop 完成 安装mahout 首先下载mahout压缩文件apache-mahout-distribution-0.12.2.tar.gz 放到/home/hadoop/software- ...

  6. CSS3设置Table奇数行和偶数行样式

    table:.myTable tr:nth-child(even){ //偶数行 background:#fff;}.myTable tr:nth-child(odd){ //奇数行 backgrou ...

  7. ionic中generate page后module.ts报错的解决办法

    此问题出现在Ionic官方将版本从2.2升级到Ionic3以上之后, 在项目中generate page时,自动创建的module.ts就报错,如下: 解决办法如下: 1)将IonicModule替换 ...

  8. js判断用户是否离开当前页面

    简介 VisibilityChange 事件:用于判断用户是否离开当前页面 Code // 页面的 visibility 属性可能返回三种状态 // prerender,visible 和 hidde ...

  9. PHP网站(Drupal7)响应过慢之“Wating(TTFB)时间过长”

    直接上图: 这是Chrome浏览器自带的工具分析的.整个url请求的时间为2.59秒,最大的耗时在Wating(TTFB, Time To First Byte),消耗了2.59秒(应该是其他时间太短 ...

  10. sqlserver年月日转汉字大写

    也是今天sql群里有人问,看起来这个问题挺简单,但是我不知道具体该怎么实现.百度了一把,找到一个高手贡献的答案,记一下. 参考链接 sql中转换中文日期 ------ 配合相关函数 ------ cr ...