`

多线程-----阻塞队列

    博客分类:
  • java
 
阅读更多
使用一个线程将一个指定目录下面的所有文件放在一个阻塞队列中,用一定数量的线程从该队列

中读取文件,然后在该文件中查找指定关键字。该程序展示了阻塞队列的功能。阻塞队列的大小

指定,当队列已满或者为空时,相应向队列放入文件的线程或者从队列中读取文件的线程将会阻

塞。该应用是一个典型的生产者-消费者模式。

源代码如下:


package com.thread.blockQueue;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * this is a BlockingQueue test
 * @author yangjianzhou
 * @description TODO
 * @time Oct 29, 2014 : 9:55:19 PM
 */
public class BlockingQueueTest {

	public static void main(String[] args) {

		String baseDirectory = "/home/yangjianzhou/document";
		String keyword = "java";
		final int FILE_QUEUE_SIZE = 10;
		final int SEARCH_THREADS = 100;

		BlockingQueue<File> queue = new ArrayBlockingQueue<File>(FILE_QUEUE_SIZE);
		FileEnumerationTask enumerator = new FileEnumerationTask(queue, new File(baseDirectory));
		new Thread(enumerator).start();
		for (int i = 1; i <= SEARCH_THREADS; i++) {
			new Thread(new SearchTask(queue, keyword)).start();
		}
	}
}

/**
 * this class is to put  file into the queue
 * @author yangjianzhou
 * @description TODO
 * @time Nov 5, 2014 : 10:30:20 PM
 */
class FileEnumerationTask implements Runnable {

	public static File DUMMY = new File("");

	private BlockingQueue<File> queue;

	private File startingDirectory;

	public FileEnumerationTask(BlockingQueue<File> queue, File startingDirectory) {
		this.queue = queue;
		this.startingDirectory = startingDirectory;
	}

	@Override
	public void run() {
		try {
			enumerate(startingDirectory);
			queue.put(DUMMY);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	/**
	 * enumerate the directory and put the  file into queue and if element is directory 
	 * and enumerate the directory and so on
	 * @param directory
	 * @throws InterruptedException
	 */
	public void enumerate(File directory) throws InterruptedException {
		File[] files = directory.listFiles();
		for (File file : files) {
			if (file.isDirectory()) {
				enumerate(file);
			} else {
				queue.put(file);
			}
		}
	}
}

/**
 * search  keyword in the blockingQueue  that  contains file
 * @author yangjianzhou
 * @description TODO
 * @time Nov 5, 2014 : 10:27:20 PM
 */
class SearchTask implements Runnable {

	private BlockingQueue<File> queue;

	private String keyword;

	public SearchTask(BlockingQueue<File> queue, String keyword) {
		this.queue = queue;
		this.keyword = keyword;
	}

	/**
	 * run the searchTask  thread , this thread gets the blockingQueue and take file from the queue 
	 * and search keyword in the file
	 */
	@Override
	public void run() {

		try {
			boolean done = false;
			while (!done) {
				/*if the queue is empty , this thread is blocked , while the queue is not empty, this thread is to run*/
				File file = queue.take();
				System.out.println("Thread name : " +Thread.currentThread().getName()+" , queue size : "+ queue.size());
				if (file == FileEnumerationTask.DUMMY) {
					queue.put(file);
					done = true;
				} else {
					search(file);
				}
			}
		} catch (Exception e) {

			e.printStackTrace();
		}
	}

	/**
	 * search keyword in the specify file , if the file contains the given keyword , print the line info
	 * @param file
	 * @throws IOException
	 */
	public void search(File file) throws IOException {
		Scanner in = new Scanner(new FileInputStream(file));
		int lineNumber = 0;
		while (in.hasNextLine()) {
			lineNumber++;
			String line = in.nextLine();
			if (line.contains(keyword)) {
				System.out.printf("%s;%d;%s%n", file.getPath(), lineNumber, line);
			}
		}
		in.close();
	}

}



运行结果:

Thread name : Thread-2 , queue size : 4
Thread name : Thread-26 , queue size : 2
Thread name : Thread-27 , queue size : 2
Thread name : Thread-25 , queue size : 4
Thread name : Thread-1 , queue size : 1
Thread name : Thread-53 , queue size : 0
Thread name : Thread-24 , queue size : 0
Thread name : Thread-56 , queue size : 9
Thread name : Thread-30 , queue size : 10
Thread name : Thread-57 , queue size : 7
Thread name : Thread-28 , queue size : 7
Thread name : Thread-58 , queue size : 6
Thread name : Thread-10 , queue size : 5
Thread name : Thread-59 , queue size : 3
Thread name : Thread-60 , queue size : 2
Thread name : Thread-61 , queue size : 1
Thread name : Thread-55 , queue size : 0
Thread name : Thread-91 , queue size : 0
Thread name : Thread-62 , queue size : 0
Thread name : Thread-96 , queue size : 9
Thread name : Thread-10 , queue size : 8
Thread name : Thread-50 , queue size : 8
Thread name : Thread-51 , queue size : 8
Thread name : Thread-6 , queue size : 8
Thread name : Thread-52 , queue size : 8
Thread name : Thread-49 , queue size : 8
Thread name : Thread-48 , queue size : 5
Thread name : Thread-47 , queue size : 6
Thread name : Thread-46 , queue size : 7
Thread name : Thread-45 , queue size : 8
Thread name : Thread-44 , queue size : 9
Thread name : Thread-7 , queue size : 10
Thread name : Thread-4 , queue size : 7
Thread name : Thread-2 , queue size : 8
Thread name : Thread-100 , queue size : 6
Thread name : Thread-35 , queue size : 0
Thread name : Thread-54 , queue size : 7
Thread name : Thread-42 , queue size : 0
Thread name : Thread-8 , queue size : 6
Thread name : Thread-41 , queue size : 1
Thread name : Thread-63 , queue size : 5
分享到:
评论

相关推荐

    支持多线程和泛型的阻塞队列

    阻塞队列是一种在多线程编程中广泛使用的并发数据结构,它在计算机科学和编程领域,特别是Java和C++等面向对象语言中扮演着重要角色。标题中的“支持多线程和泛型的阻塞队列”意味着我们讨论的是一个能够同时处理多...

    android NDK实现的Hanlder-消息队列-native多线程实例

    本实例关注的是如何在Android NDK环境下实现一个类似Java层的消息队列(Message Queue)和Handler机制,以及如何在原生代码中创建和管理多线程。 首先,我们要理解Java层的Handler和消息队列的工作原理。在Java中,...

    线程-线程池-锁-集合-Map-队列.docx

    `ArrayBlockingQueue`、`LinkedBlockingQueue`等是常见的阻塞队列实现,它们在多线程环境中能确保线程安全。 综上所述,线程、线程池、集合和队列是Java并发编程的核心概念,理解和掌握它们对于开发高效、稳定的...

    java 多线程 队列工厂

    阻塞队列在多线程环境中特别有用,因为它允许线程在队列满时等待,直到有空间可用;同样,当队列为空时,取元素的线程也会被阻塞,直到有新的元素插入。 常见的`BlockingQueue`实现包括`ArrayBlockingQueue`、`...

    多线程 队列利用

    在IT行业中,多线程和队列是两个关键的概念,特别是在并发编程和高效系统设计中。本篇文章将深入探讨这两个概念及其结合应用。 首先,让我们理解“多线程”。多线程是计算机程序设计中的一个技术,允许一个应用程序...

    典型的多线程--生产和消费

    "典型的多线程--生产和消费"这个主题,通常指的是生产者-消费者问题,这是一种经典的设计模式,用于解决如何在一个数据结构(如队列)中高效地存储和检索数据,同时避免生产者过于快速地生成数据而消费者无法及时...

    RabbitMQ实战-多线程-springboot-rabbit.zip

    在本项目"RabbitMQ实战-多线程-springboot-rabbit.zip"中,我们将深入探讨如何使用RabbitMQ作为消息中间件,结合Spring Boot框架和多线程技术来实现高效、可扩展的分布式系统。Spring Boot简化了RabbitMQ的集成,而...

    workquere工作队列 多线程

    工作队列(Work Queue)是一种在多线程编程中广泛使用的模式,用于协调并发任务的执行,优化系统资源的利用并提高程序的响应速度。在C#中,工作队列通常用于将耗时的任务放入队列,然后由一组后台线程来处理这些任务...

    多线程-day03.docx

    【多线程-day03.docx】文档主要讨论了如何实现一个高效的秒杀系统,其中涉及到了多线程技术在高并发场景下的应用。以下是基于文档内容解析出的相关知识点: 1. **秒杀业务流程**: - 商家提交秒杀商品申请,包括...

    多线程任务队列

    在编程领域,尤其是在性能敏感的系统中,多线程任务队列是一种常见且重要的设计模式。这个主题主要涉及C++编程语言,它利用了C++的特性来实现高效的并发处理。下面将详细介绍“多线程任务队列”的概念、工作原理以及...

    彻底明白Java的多线程-线程间的通信.doc

    Java的多线程是编程中的一个关键概念,特别是在并发处理和高性能应用中。本文将深入讲解如何在Java中实现多线程以及线程间的通信。 首先,我们要理解一个虚假的多线程示例。在例1中,创建了两个`TestThread`对象,...

    多线程操作日志队列

    在多线程日志处理中,队列充当了生产者和消费者之间的缓冲区,确保了日志的顺序,并防止了生产者过快导致的内存溢出或者消费者过慢导致的阻塞。 3. **线程执行器(Thread Pool)**:线程执行器,也称为线程池,是...

    java多线程加队列上传文件_后台处理

    ### Java多线程加队列上传文件_后台处理 #### 概述 本文将详细介绍一个基于Java实现的多线程文件上传系统,并结合队列管理技术来优化后台处理流程。该系统通过创建多个线程来并行处理客户端的文件上传请求,同时...

    多线程-狂神说Java学习笔记

    **多线程在Java中的应用与理解** Java中的多线程是并发编程的重要组成部分,它允许程序同时执行多个任务,从而提高系统效率和资源利用率。本学习笔记将深入探讨Java多线程的相关知识,包括其原理、实现方式、同步...

    Linux下使用EPoll+队列+多线程的C++实现

    在这个“Linux下使用EPoll+队列+多线程的C++实现”项目中,开发者使用了`epoll`来监听并管理TCP服务器的连接。`epoll`的工作流程大致如下: 1. **创建epoll句柄**:首先,通过`epoll_create()`函数创建一个epoll...

    线程----BlockingQueue

    `BlockingQueue`是一种特殊类型的队列,主要用于多线程环境中的任务管理。它具有以下特性:当队列为空时,从队列中获取元素的操作会被阻塞;同样地,当队列满时,向队列中添加元素的操作也会被阻塞。这种特性使得`...

    iOS多线程-GCD(异步任务,线程锁)

    在iOS开发中,多线程技术是不可或缺的一部分,它能够帮助我们提高应用程序的性能和用户体验。GCD(Grand Central Dispatch)是苹果推出的一种强大的多线程解决方案,它为开发者提供了简单而高效的方式来管理并发任务...

    QT-线程阻塞问题-开启多线程(帮助你快速解决因大量计算耗时而导致主线程渲染阻塞的问题、简单实现多线程教学)

    我们经常会进行一些比较复杂的计算和算法实现,或者是在某些特定的情况下会实例化一些类。...可以通过开启子线程,将复杂计算内容交给子线程来处理,主线程主要进行UI的渲染操作,这样同样能够解决线程阻塞的问题。

    vc socket tcp 多线程客户端--服务器结构的例子.visual c++

    本文将深入探讨基于Visual C++的TCP多线程客户端-服务器结构,并以"vc socket tcp 多线程客户端--服务器结构的例子"为例进行解析。这个例子包含了一个名为"RawSocketServerExample"的文件,很可能是实现此架构的源...

    多线程队列

    3. **非阻塞操作**:设计良好的多线程队列应尽可能减少线程之间的等待,以提高效率。当队列为空或满时,应提供非阻塞的策略,如返回错误、等待或者超时。 4. **并发控制**:使用条件变量或者信号量等机制,可以有效...

Global site tag (gtag.js) - Google Analytics