阻塞队列java代码 阻塞队列源码

java中如何对某个方法或者某个代码块使用阻塞队列来保证并发情况下线程是安全的synchronize加在函数方法或者代码块阻塞队列java代码,就能按阻塞队列java代码你说阻塞队列java代码的保证线程安全阻塞队列java代码,原理是多线程进入时候系统会只允许一个线程执行那些语句
java priorityqueue 哪些方法1.下表显示了jdk1.5中的阻塞队列的操作:
add增加一个元索如果队列已满 , 则抛出一个IIIegaISlabEepeplian异常
remove移除并返回队列头部的元素如果队列为空,则抛出一个NoSuchElementException异常
element返回队列头部的元素如果队列为空,则抛出一个NoSuchElementException异常
offer添加一个元素并返回true如果队列已满,则返回false
poll移除并返问队列头部的元素如果队列为空,则返回null
peek返回队列头部的元素如果队列为空 , 则返回null
put添加一个元素如果队列满,则阻塞
take移除并返回队列头部的元素如果队列为空,则阻塞
remove、element、offer 、poll、peek 其实是属于Queue接口 。
2.阻塞队列的操作可以根据它们的响应方式分为以下三类:aad、removee和element操作在你试图为一个已满的队列增加元素或从空队列取得元素时 抛出异常 。当然,在多线程程序中,队列在任何时间都可能变成满的或空的,所以你可能想使用offer、poll、peek方法 。这些方法在无法完成任务时 只是给出一个出错示而不会抛出异常 。
注意:poll和peek方法出错进返回null 。因此,向队列中插入null值是不合法的 。
3.还有带超时的offer和poll方法变种,例如,下面的调用:
boolean success = q.offer(x,100,TimeUnit.MILLISECONDS);
尝试在100毫秒内向队列尾部插入一个元素 。如果成功,立即返回true;否则,当到达超时进,返回false 。同样地,调用:
Object head = q.poll(100, TimeUnit.MILLISECONDS);
如果在100毫秒内成功地移除了队列头元素,则立即返回头元素;否则在到达超时时,返回null 。
4.最后 , 我们有阻塞操作put和take 。put方法在队列满时阻塞,take方法在队列空时阻塞 。
java.ulil.concurrent包提供了阻塞队列的4个变种 。默认情况下,LinkedBlockingQueue的容量是没有上限的(说的不准确,在不指定时容量为Integer.MAX_VALUE,不要然的话在put时怎么会受阻呢),但是也可以选择指定其最大容量 , 它是基于链表的队列,此队列按 FIFO(先进先出)排序元素 。
ArrayBlockingQueue在构造时需要指定容量,并可以选择是否需要公平性,如果公平参数被设置true,等待时间最长的线程会优先得到处理(其实就是通过将ReentrantLock设置为true来 达到这种公平性的:即等待时间最长的线程会先操作) 。通常,公平性会使你在性能上付出代价 , 只有在的确非常需要的时候再使用它 。它是基于数组的阻塞循环队 列 , 此队列按 FIFO(先进先出)原则对元素进行排序 。
PriorityBlockingQueue是一个带优先级的 队列,而不是先进先出队列 。元素按优先级顺序被移除,该队列也没有上限(看了一下源码,PriorityBlockingQueue是对 PriorityQueue的再次包装,是基于堆数据结构的,而PriorityQueue是没有容量限制的,与ArrayList一样,所以在优先阻塞 队列上put时是不会受阻的 。虽然此队列逻辑上是无界的 , 但是由于资源被耗尽 , 所以试图执行添加操作可能会导致 OutOfMemoryError),但是如果队列为空,那么取元素的操作take就会阻塞,所以它的检索操作take是受阻的 。另外,往入该队列中的元 素要具有比较能力 。
java阻塞有界队列,需要一次添加多个元素,要么都添加到阻塞队列,要么一个都不添加到阻塞队列就按你说阻塞队列java代码的实现呗, 我看你说的挺明白的.
加入之前先判断阻塞队列java代码,队列]空位够不够阻塞队列java代码,够了就加阻塞队列java代码,不够就不加
阻塞队列阻塞队列常用于生产者和消费者的场景,生产者就是往队列中放入元素,消费者就是从队列中获取元素,阻塞队列就是生产者存放元素的容器,而消费者也从该容器中拿元素 。
阻塞队列有两种常见的阻塞场景,满足这两种阻塞场景的队列就是阻塞队列,分别如下:
Java中提供了7个阻塞队列,分别如下:
ArrayBlockingQueue和LinkedBlockingQueue一般为常用的阻塞队列 。
接下来通过一个Demo演示阻塞队列的用法 。
这里维护了一个ArrayBlockingQueue,并指定其大小为10,创建了一个生产者线程和一个消费者线程,生产者线程在生产5个事件后睡两秒钟,消费者线程在消费完“事件 - 5”后由于从队列中拿不到元素,就会自动阻塞,等待生产者往队列中放入元素,只要队列中有生产者放入元素,就会立即唤醒消费者线程继续获取元素,详见以下Log:
下面通过分析ArrayBlockingQueue的原理加深对阻塞队列的理解 。
在生产者消费模型中,生产数据和消费数据的速率不一致,如果生产数据速度快一些,消费不过来,就会导致数据丢失,这时候我们就可以使用阻塞队列来解决这个问题 。
阻塞队列是一个队列,我们使用单线程生产数据,使用多线程消费数据 。由于阻塞队列的特点:队列为空的时候消费者端阻塞,队列满的时候生产者端阻塞 。多线程消费数据起到了加速消费的作用,使得生产的数据不会在队列里积压过多,而生产的数据也不会丢失处理 。
java阻塞队列 线程同步合作 Queue接口与List Set同一级别 都是继承了Collection接口 LinkedList实现了Queue接口 Queue接口窄化了对LinkedList阻塞队列java代码的方法的访问权限(即在方法中的参数类型如果是Queue时 就完全只能访问Queue接口所定义的方法了 而不能直接访问 LinkedList的非Queue的方法) 以使得只有恰当的方法才可以使用 BlockingQueue 继承了Queue接口
队列是一种数据结构.它有两个基本操作 在队列尾部加人一个元素 和从队列头部移除一个元素就是说 队列以一种先进先出的方式管理数据 如果阻塞队列java代码你试图向一个已经满了的阻塞队列中添加一个元素或者是从一个空的阻塞队列中移除一个元索 将导致线程阻塞.在多线程进行合作时 阻塞队列是很有用的工具 工作者线程可以定期地把中间结果存到阻塞队列中而其阻塞队列java代码他工作者线线程把中间结果取出并在将来修改它们 队列会自动平衡负载 如果第一个线程集运行得比第二个慢 则第二个线程集在等待结果时就会阻塞 如果第一个线程集运行得快 那么它将等待第二个线程集赶上来 下表显示了jdk 中的阻塞队列的操作
add增加一个元索如果队列已满 则抛出一个IIIegaISlabEepeplian异常
remove移除并返回队列头部的元素如果队列为空 则抛出一个NoSuchElementException异常
element返回队列头部的元素如果队列为空 则抛出一个NoSuchElementException异常
offer添加一个元素并返回true如果队列已满 则返回false
【阻塞队列java代码 阻塞队列源码】 poll移除并返问队列头部的元素如果队列为空 则返回null
peek返回队列头部的元素如果队列为空 则返回null
put添加一个元素如果队列满 则阻塞
take移除并返回队列头部的元素如果队列为空 则阻塞
remove element offer poll peek 其实是属于Queue接口
阻塞队列的操作可以根据它们的响应方式分为以下三类 aad removee和element操作在你试图为一个已满的队列增加元素或从空队列取得元素时抛出异常 当然 在多线程程序中 队列在任何时间都可能变成满的或空的 所以你可能想使用offer poll peek方法 这些方法在无法完成任务时只是给出一个出错示而不会抛出异常
注意 poll和peek方法出错进返回null 因此 向队列中插入null值是不合法的
还有带超时的offer和poll方法变种 例如 下面的调用
boolean success = q offer(x TimeUnit MILLISECONDS);
尝试在 毫秒内向队列尾部插入一个元素 如果成功 立即返回true 否则 当到达超时进 返回false 同样地 调用
Object head = q poll( TimeUnit MILLISECONDS);
如果在 毫秒内成功地移除了队列头元素 则立即返回头元素 否则在到达超时时 返回null
最后 我们有阻塞操作put和take put方法在队列满时阻塞 take方法在队列空时阻塞
ncurrent包提供了阻塞队列的 个变种 默认情况下 LinkedBlockingQueue的容量是没有上限的(说的不准确 在不指定时容量为Integer MAX_VALUE 不要然的话在put时怎么会受阻呢) 但是也可以选择指定其最大容量 它是基于链表的队列 此队列按 FIFO(先进先出)排序元素
ArrayBlockingQueue在构造时需要指定容量 并可以选择是否需要公平性 如果公平参数被设置true 等待时间最长的线程会优先得到处理(其实就是通过将ReentrantLock设置为true来达到这种公平性的 即等待时间最长的线程会先操作) 通常 公平性会使你在性能上付出代价 只有在的确非常需要的时候再使用它 它是基于数组的阻塞循环队列 此队列按 FIFO(先进先出)原则对元素进行排序
PriorityBlockingQueue是一个带优先级的队列 而不是先进先出队列 元素按优先级顺序被移除 该队列也没有上限(看了一下源码 PriorityBlockingQueue是对PriorityQueue的再次包装 是基于堆数据结构的 而PriorityQueue是没有容量限制的 与ArrayList一样 所以在优先阻塞队列上put时是不会受阻的 虽然此队列逻辑上是无界的 但是由于资源被耗尽 所以试图执行添加操作可能会导致 OutOfMemoryError) 但是如果队列为空 那么取元素的操作take就会阻塞 所以它的检索操作take是受阻的 另外 往入该队列中的元素要具有比较能力
最后 DelayQueue(基于PriorityQueue来实现的)是一个存放Delayed 元素的无界阻塞队列 只有在延迟期满时才能从中提取元素 该队列的头部是延迟期满后保存时间最长的 Delayed 元素 如果延迟都还没有期满 则队列没有头部 并且poll将返回null 当一个元素的 getDelay(TimeUnit NANOSECONDS) 方法返回一个小于或等于零的值时 则出现期满 poll就以移除这个元素了 此队列不允许使用 null 元素 下面是延迟接口
Java代码
public interface Delayed extends ComparableDelayed {
long getDelay(TimeUnit unit);
}
public interface Delayed extends ComparableDelayed {
long getDelay(TimeUnit unit);
}
放入DelayQueue的元素还将要实现pareTo方法 DelayQueue使用这个来为元素排序
下面的实例展示了如何使用阻塞队列来控制线程集 程序在一个目录及它的所有子目录下搜索所有文件 打印出包含指定关键字的文件列表 从下面实例可以看出 使用阻塞队列两个显著的好处就是 多线程操作共同的队列时不需要额外的同步 另外就是队列会自动平衡负载 即那边(生产与消费两边)处理快了就会被阻塞掉 从而减少两边的处理速度差距 下面是具体实现
Java代码
public class BlockingQueueTest {
public static void main(String[] args) {
Scanner in = new Scanner(System in);
System out print( Enter base directory (e g /usr/local/jdk /src): );
String directory = in nextLine();
System out print( Enter keyword (e g volatile): );
String keyword = in nextLine();
final int FILE_QUEUE_SIZE = ;// 阻塞队列大小
final int SEARCH_THREADS = ;// 关键字搜索线程个数
// 基于ArrayBlockingQueue的阻塞队列
BlockingQueueFile queue = new ArrayBlockingQueueFile(
FILE_QUEUE_SIZE);
//只启动一个线程来搜索目录
FileEnumerationTask enumerator = new FileEnumerationTask(queue
new File(directory));
new Thread(enumerator) start();
//启动 个线程用来在文件中搜索指定的关键字
for (int i = ; i = SEARCH_THREADS; i)
new Thread(new SearchTask(queue keyword)) start();
}
}
class FileEnumerationTask implements Runnable {
//哑元文件对象 放在阻塞队列最后 用来标示文件已被遍历完
public static File DUMMY = new File( );
private BlockingQueueFile queue;
private File startingDirectory;
public FileEnumerationTask(BlockingQueueFile queue File startingDirectory) {
this queue = queue;
this startingDirectory = startingDirectory;
}
public void run() {
try {
enumerate(startingDirectory);
queue put(DUMMY);//执行到这里说明指定的目录下文件已被遍历完
} catch (InterruptedException e) {
}
}
// 将指定目录下的所有文件以File对象的形式放入阻塞队列中
public void enumerate(File directory) throws InterruptedException {
File[] files = directory listFiles();
for (File file : files) {
if (file isDirectory())
enumerate(file);
else
//将元素放入队尾 如果队列满 则阻塞
queue put(file);
}
}
}
class SearchTask implements Runnable {
private BlockingQueueFile queue;
private String keyword;
public SearchTask(BlockingQueueFile queue String keyword) {
this queue = queue;
this keyword = keyword;
}
public void run() {
try {
boolean done = false;
while (!done) {
//取出队首元素 如果队列为空 则阻塞
File file = queue take();
if (file == FileEnumerationTask DUMMY) {
//取出来后重新放入 好让其阻塞队列java代码他线程读到它时也很快的结束
queue put(file);
done = true;
} else
search(file);
}
} catch (IOException e) {
e printStackTrace();
} catch (InterruptedException e) {
}
}
public void search(File file) throws IOException {
Scanner in = new Scanner(new FileInputStream(file));
int lineNumber = ;
while (in hasNextLine()) {
lineNumber;
String line = in nextLine();
if (ntains(keyword))
System out printf( %s:%d:%s%n file getPath() lineNumber
line);
}
in close();
}
lishixinzhi/Article/program/Java/hx/201311/26657
阻塞队列java代码的介绍就聊到这里吧 , 感谢你花时间阅读本站内容,更多关于阻塞队列源码、阻塞队列java代码的信息别忘了在本站进行查找喔 。

    推荐阅读