zoukankan      html  css  js  c++  java
  • 查找表

    1 下列属于线程安全类的是:

    A.StringBuffer

    B.StringBuilder

    C.ArrayList

    D.HashMap

    参考答案

    本题正确答案为A。

    StringBuffer属于线程安全的类;StringBuilder、ArrayList、HashMap是非线程安全类。

    2 使用BlockingQueue实现生产者和消费者模型

    参考答案

    在工作中,可能会碰到这样一种情况:某个模块负责产生数据,这些数据由另一个模块来负责处理。产生数据的模块,则形象地称为生产者;而处理数据的模块,则称为消费者。在生产者与消费者之间在加个缓冲区,我们形象的称之为仓库,生产者负责往仓库了进商品,而消费者负责从仓库里拿商品,这就构成了生产者消费者模式。生产者和消费者模型的结构如图-1所示。

    图-1

    在实际工作中,典型的生产者消费者模型的案例是流媒体在线现在播放。流媒体下载是生产者;流媒体播放是消费者,如图-2所示。

    图-2

    以下案例使用BlockingQueue实现生产者和消费者模型,模拟了流媒体下载视频数据和播放视频的过程。

    实现此案例需要按照如下步骤进行。

    步骤一:创建生产者

    首先新建Donwload类,在该类中模拟视频数据下载的过程,其中BlockingQueue对象则是在上文中提到的缓冲区,Donwload对象负责向该缓冲区存储数据,代码如下所示:

     
    1. import java.util.concurrent.BlockingQueue;
    2. public class Donwload implements Runnable {
    3.     private final BlockingQueue<Object> queue;
    4.     public Donwload(BlockingQueue<Object> q) {
    5.         queue = q;
    6.     }
    7.     public void run() {
    8.         try {
    9.             while (true) {
    10.                 System.out.println("下载视频数据"+index);
    11.                 queue.put(produce());                
    12.             }
    13.         } catch (InterruptedException ex) {
    14.         }
    15.     }
    16.     int index=0;
    17.     public Object produce() {
    18.         try {
    19.             Thread.sleep(5000);
    20.         } catch (InterruptedException e) {
    21.             e.printStackTrace();
    22.         }
    23.         return "视频数据"+index++;
    24.     }
    25. }

    步骤二:创建消费者

    新建类Player,在该类中实现模拟播放视频的过程,其中BlockingQueue对象也是在上文中提到的缓冲区,Player对象负责从该缓冲区中取数据,代码如下所示:

     
    1. import java.util.concurrent.BlockingQueue;
    2. public class Player implements Runnable {
    3.     private final BlockingQueue<Object> queue;
    4.     public Player(BlockingQueue<Object> q) {
    5.         queue = q;
    6.     }
    7.     public void run() {
    8.         try {
    9.             while (true) {
    10.                 consume(queue.take());
    11.             }
    12.         } catch (InterruptedException ex) {
    13.         }
    14.     }
    15.     void consume(Object x) {
    16.         System.out.println("播放"+x);
    17.     }
    18. }

    步骤三:启动线程

    首先新建Setup类,在该类的main方法中,创建缓冲区BlockingQueue对象并将该对象传给下载器和播放器,这样就保证了下载器和播放器使用了相同的缓冲区。代码如下所示:

     
    1. import java.util.concurrent.ArrayBlockingQueue;
    2. import java.util.concurrent.BlockingQueue;
    3. public class Setup {
    4.     public static void main(String[] args) {
    5.         BlockingQueue<Object> q = new ArrayBlockingQueue<Object>(10);
    6.         Donwload p = new Donwload(q);
    7.         Player c1 = new Player(q);
    8.         Player c2 = new Player(q);
    9.         new Thread(p).start();
    10.         new Thread(c1).start();
    11.         new Thread(c2).start();
    12.     }
    13. }

    从上述代码中,可以看出有一个线程负责下载,两个线程负责播放。

    步骤四:运行

    运行上述代码,由于程序在不断的运行,所以图-3是截取控制台的部分数据。

    图-3

    从图-3的输出结果可以看出,只有下载数据完成后该数据才能播放,这是因为,BlockingQueue内部使用两条队列,可允许两个线程同时向队列一个做存储,一个做取出操作。如果BlockingQueue对象是空的,则从BlockingQueue对象取数据的操作将会被阻塞进入等待状态,直到BlockingQueue对象有数据进入则被唤醒。同样,如果BlockingQueue对象是满的,任何试图向其存数据的操作也会被阻塞进入等待状态,直到BlockingQueue对象内有空间则会被唤醒继续操作,这样,BlockingQueue对象保证并发安全的同时提高了队列的存取效率。

  • 相关阅读:
    hdu 3652 【数位dp】
    02 -body标签中相关标签
    01-html介绍和head标签
    python 核心编程第九章文件
    python核心编程 第七章 字典,集合 练习
    常用链接
    python核心编程 第七章 字典
    python核心编程 第六章 字符串,元组,列表 字符串元组只读不可变。列表可变。
    python核心编程 第五章 数字
    python读取文件中的路径内容,保存到另外的路径中
  • 原文地址:https://www.cnblogs.com/xyk1987/p/8330961.html
Copyright © 2011-2022 走看看