多线程13-阻塞队列

1. 概念

阻塞队列的概念和前面提到的缓冲区的概念类似,常见一个固定长队的队列 ,如果队列满的时候 put数据则一致会阻塞等待,直到队列数据被取走后会立即执行put数据操作

同样的道理,如果队列为空时进行取数据take操作,则一直会阻塞等待,知道有线程执行了put数据到队列中后才会立即执行take数据的操作.

2.代码

package org.lkl.thead.foo;

import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class BlockQueueFoo {

    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newCachedThreadPool() ;
        //申明一个长度为5的队列
        final BlockingQueue<Long> queue = new ArrayBlockingQueue<Long>(5) ; 

        //put操作  开启三个线程来put数据
        for(int i = 1 ;i<=3 ;i++){
            Runnable r = new Runnable() {

                @Override
                public void run() {
                    while(true){
                        try {
                                Thread.sleep(1000);
                                Long r =  new Random().nextLong() ;
                                queue.put(r) ;
                                System.out.println(Thread.currentThread().getName()+" put :"+r+" queue size:"+queue.size());
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            };

            threadPool.execute(r) ;
        }
        //开启一个线程取数据
        new Thread(new Runnable() {

            @Override
            public void run() {

                while(true){
                    try {
                        Thread.sleep(200);
                        Long r = queue.take();
                        System.out.println(Thread.currentThread().getName()+" take "+ r+" queue size : "+queue.size());
                    } catch (Exception e) {
                        // TODO: handle exception
                    }
                }
            }
        }).start() ;

    }
}

3. 通过阻塞队列来实现线程之间的通信

修改前面的代码  子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,然后再回到主线程又循环100次,如此循环50次  通过阻塞队列来实现线程之间的通信

代码: 

package cn.itcast.heima2;

import java.util.Collections;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

public class BlockingQueueCommunication {

    /**
     * @param args
     */
    public static void main(String[] args) {

        final Business business = new Business();
        new Thread(
                new Runnable() {

                    @Override
                    public void run() {

                        for(int i=1;i<=50;i++){
                            business.sub(i);
                        }

                    }
                }
        ).start();

        for(int i=1;i<=50;i++){
            business.main(i);
        }

    }

     static class Business {

          BlockingQueue<Integer> queue1 = new ArrayBlockingQueue<Integer>(1);
          BlockingQueue<Integer> queue2 = new ArrayBlockingQueue<Integer>(1);

          {
              Collections.synchronizedMap(null);
              try {
                  System.out.println("xxxxxdfsdsafdsa");
                queue2.put(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
          }

          public  void sub(int i){
                  try {
                    queue1.put(1);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                for(int j=1;j<=10;j++){
                    System.out.println("sub thread sequece of " + j + ",loop of " + i);
                }
                try {
                    queue2.take();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
          }

          public  void main(int i){
                  try {
                    queue2.put(1);
                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                for(int j=1;j<=100;j++){
                    System.out.println("main thread sequece of " + j + ",loop of " + i);
                }
                try {
                    queue1.take();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
          }
      }

}

多线程13-阻塞队列

时间: 2024-12-14 09:48:44

多线程13-阻塞队列的相关文章

多线程之阻塞队列ArrayBlockingQueue,BlockingQueue

ArrayBlockingQueue是个有数组支持的有界的阻塞队列.该队列按照先进先出FIFO的原理对元素排序,插入新元素市场队列的尾部,获取新元素是操作队列的开始处.一旦见了建立了缓存区,就不能再增加其容量,试图从已满的队列中方式元素会导致操作阻塞:试图从空的队列中提取元素将导致阻塞. 提拱了四种方法,只有put(),take()才会发生阻塞. 下面是阻塞队列的例子. package andy.thread.test; import java.util.concurrent.ArrayBloc

Java多线程-新特征-阻塞队列ArrayBlockingQueue

阻塞队列是Java5线程新特征中的内容,Java定义了阻塞队列的接口java.util.concurrent.BlockingQueue,阻塞队列的概念是,一个指定长度的队列,如果队列满了,添加新元素的操作会被阻塞等待,直到有空位为止.同样,当队列为空时候,请求队列元素的操作同样会阻塞等待,直到有可用元素为止. 有了这样的功能,就为多线程的排队等候的模型实现开辟了便捷通道,非常有用. java.util.concurrent.BlockingQueue继承了java.util.Queue接口,可

Java多线程——阻塞队列

现在,通过前几篇的总结,我们对Java多线程已经有所了解了,但是它们都是一些Java并发程序设计基础的底层构建块.对于实际编程来说,我们应该尽可能的远离底层结构.使用那些由并发处理的专业人士实现的较高层次的结构要方便的多,安全的多. 阻塞队列 对于许多线程问题.可以通过使用一个或多个队列以优雅且安全的方式将其形式化.生产者线程向队列插入元素,消费者线程则取出他们.使用队列,可以安全地从一个线程向另一个线程传递数据. 阻塞队列的方法 方法 正常动作 特殊情况下动作 add 添加一个元素 如果队列满

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

1.什么是阻塞队列? 所谓队列,遵循的是先进先出原则(FIFO),阻塞队列,即是数据共享时,A在写数据时,B想读同一数据,那么就将发生阻塞了. 看一下线程的四种状态,首先是新创建一个线程,然后,通过start方法启动线程--->线程变为可运行可执行状态,然后通过数据产生共享,线程产生互斥---->线程状态变为阻塞状态---->阻塞状态想打开的话可以调用notify方法. 这里Java5中提供了封装好的类,可以直接调用然后构造阻塞状态,以保证数据的原子性. 2.如何实现? 主要是实现Blo

Java多线程与并发库高级应用之阻塞队列BlockingQueue

JDK1.5提供了阻塞队列接口BlockingQueue,它是一个有界阻塞队列.BlockingQueue实现是线程安全的,可以安全地与多个生产者和多个使用者一起使用. 使用时用其实现类 ArrayBlockingQueue,它一个由数组支持的有界阻塞队列.此队列按 FIFO(先进先出)原则对元素进行排序.队列的头部 是在队列中存在时间最长的元素.队列的尾部是在队列中存在时间最短的元素.新元素插入到队列的尾部,队列获取操作则是从队列头部开始获得元素. 这是一个典型的"有界缓存区",固定

Java多线程 阻塞队列和并发集合

转载:大关的博客 Java多线程 阻塞队列和并发集合 本章主要探讨在多线程程序中与集合相关的内容.在多线程程序中,如果使用普通集合往往会造成数据错误,甚至造成程序崩溃.Java为多线程专门提供了特有的线程安全的集合类,通过下面的学习,您需要掌握这些集合的特点是什么,底层实现如何.在何时使用等问题. 3.1 BlockingQueue接口 java阻塞队列应用于生产者消费者模式.消息传递.并行任务执行和相关并发设计的大多数常见使用上下文. BlockingQueue在Queue接口基础上提供了额外

多线程编程-之并发编程:阻塞队列

在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList),这些工具都为我们编写多线程程序提供了很大的方便.今天我们来讨论另外一类容器:阻塞队列. 在前面我们接触的队列都是非阻塞队列,比如PriorityQueue.LinkedList(LinkedList是双向链表,它实现了Dequeue接口). 使用非阻塞队列的时候有一个很大问题就是:它不会对当前线程产生阻塞,那么在面对类似消费者

跟我学Java多线程——线程池与阻塞队列

前言 上一篇文章中我们将ThreadPoolExecutor进行了深入的学习和介绍,实际上我们在项目中应用的时候很少有直接应用ThreadPoolExecutor来创建线程池的,在jdk的api中有这么一句话"但是,强烈建议程序员使用较为方便的 Executors 工厂方法Executors.newCachedThreadPool()(无界线程池,可以进行自动线程回收).Executors.newFixedThreadPool(int)(固定大小线程池)和Executors.newSingleT

java多线程(九)阻塞队列

转载请注明出处:http://blog.csdn.net/xingjiarong/article/details/48005091 前边的博客中我们介绍了如果用对象锁和条件锁以及更加方便的synchronized关键字来实现多线程的同步和互斥,也许你会觉得使用synchronized关键字已经非常方便了,但是使用者必须真正的理解synchronized的用法,而且要有一定的多线程的编程的经验,否则很难做到全面的考虑问题而造成意想不到的问题.其实在java中还有比synchronized关键字更加

多线程之消费者生产者模式加入阻塞队列

队列相关资料: http://chenjumin.iteye.com/blog/2182322 http://blog.csdn.net/luohuacanyue/article/details/16359777 Queue ------------ 1.ArrayDeque, (数组双端队列) 2.PriorityQueue, (优先级队列) 3.ConcurrentLinkedQueue, (基于链表的并发队列) 4.DelayQueue, (延期阻塞队列)(阻塞队列实现了BlockingQ