CoreJava_线程并发(阻塞队列):在某个文件夹下搜索含有某关键字的文件

Java多线程编程是非常考验一个程序员水平的。传统的WEB程序中,因为框架提供了太多的健壮性、并发性、可靠性的支持,所以我们都是将所有的注意力放到了业务实现上。我们只是按照业务逻辑的要求,不停的积累自己的代码。因为知识,或者是经验的限制,经常出现了问题而不自知。例如,某些比较原始的项目中,并没有使用Spring等相对来说比较灵活健壮的框架。而是仅仅使用Servlet来作为服务端的实现方式。

举一个简单的栗子,众所周知,当请求到了容器,容器是创建并且启动了一个Servlet线程来对当前的请求作出相应,这个时候,Servlet中的成员变量就会受到多线程的影响,这样,在Servlet中书写成员变量代码就会变得非常的危险,因为毕竟不是一个线程安全的设计。多线程的同步、互斥、竞争、配合以及线程的中断等成了我们在编码过程中,非常注意的一个知识点。

Java核心技术中,说到如何对多线程进行并发控制:首先:建议使用阻塞队列,阻塞队列是由专业的线程安全的一个数据结构,我们在这个上面进行编程,就如同站在巨人的肩膀上,至于很多低层的实现就是他们去考虑的事情了。其次,如果想自己控制多线程并发的时候,尽可能的推荐使用synchronized关键字,synchronized关键字实际上就是等同于ReentrantLock或者读写锁的实现,不过语法更加简洁,更不太容易出错。FINALLY,最后,如果有充足的理由的时候,才会推荐使用ReentrantLock或者ReentrantReadWriteLock、ReadLock、WriteLock以及其相应的condition条、volatile等等,因为这些太过于低层,而且按照java一贯的实现编码逻辑,我们只需要知道某一个控制线程并发数据结构的存在就可以了。

下面是在核心技术上的一个非常好的,可以用来研究阻塞队列的Demo,目的是用于在某一个给定的文件夹下面,搜索所有含有某个关键字的文件,这中功能在很多编辑器下都有具体的实现,例如UE。

功能的实现方式大概是这样的:生产者线程,将当前给定的文件夹下面的所有的文件,放到阻塞队列中(功能实现中使用了递归),最后,放置一个空的文件,作为一个标志,类似于一个信号灯的样子。创建了非常多的消费者线程,从阻塞队列中,循环获取一个文件,然后进行逐行遍历,如果当中含有关键字则打印,跳出循环的条件是看到了消费者线程放置的信号灯。功能的实现将并发依赖于一个并发的数据结构,很值得去借鉴。

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;

public class BlockingQueueTest {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		System.out.println("Enter base directory(eg. /usr/local/jdk1.6.0/src)");
		String directory = in.nextLine();
		System.out.println("Enter keyword(e.g. volatile):");
		String keyword = in.nextLine();

		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(directory));
		new Thread(enumerator).start();
		for(int i=1;i<=SEARCH_THREADS;i++){
			new Thread(new SearchTask(queue,keyword)).start();
		}
	}
}

class FileEnumerationTask implements Runnable{

	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){
		}
	}
	public void enumerate(File directory)throws InterruptedException{
		File[] files = directory.listFiles();
		for(File file : files){
			if(file.isDirectory())enumerate(file);
			else queue.put(file);
		}
	}
	public static File DUMMY = new File("");

	private BlockingQueue<File> queue;
	private File startingDirectory;
}

class SearchTask implements Runnable{
	public SearchTask(BlockingQueue<File> queue,String keyword){
		this.queue = queue;
		this.keyword = keyword;
	}
	@Override
	public void run() {
		try {
			boolean done = false;
			while(!done){
				File file = queue.take();
				if(file==FileEnumerationTask.DUMMY){
					queue.put(file);
					done=true;
				}
				else {
					search(file);
				}
			}
		}catch(IOException e){

		}
		catch (InterruptedException e) {
		}
	}

	private 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();
	}

	private BlockingQueue<File> queue;
	private String keyword;
}

CoreJava_线程并发(阻塞队列):在某个文件夹下搜索含有某关键字的文件,布布扣,bubuko.com

时间: 2024-10-15 20:41:36

CoreJava_线程并发(阻塞队列):在某个文件夹下搜索含有某关键字的文件的相关文章

模拟test文件下的201712{01..31}/pdf这些文件夹下都有100个pdf文件

1.模拟test文件下的201712{01..31}/pdf这些文件夹下都有100个pdf文件注意灰色部分有反引号[[email protected] ~]# cat b.sh#!/bin/bashcd /root/test && mkdir -p 201712{01..31}/pdfWJ=find /root/moban -type ffor f in find /root/test/201712{01..31}/pdf -type ddocp $WJ $f &>/dev/

Java实现读取文件夹下(包括子目录)所有文件的文件名

在编程的过程中,经常会用到对文件的读写操作等.比如,找出某一个文件夹下的所有文件名等. 下面的程序给出了,获取某一给定文件夹下所有文件的绝对路径的程序.可以作为某一个模块,在需要的时候直接使用. package src; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStrea

matlab遍历文件夹下所有图片和遍历所有子文件夹下图片

做图像处理实验,经常需要遍历当前文件下所有图片.matlab当然很早就考虑了这个问题,库函数dir就是完成这个工作的.函数返回的是一个存放所有目录下文件信息的结构体,通过遍历结构体就可以达到访问所有文件的目的了.具体实现见下面程序: imgPath = 'E:/imageData/'; % 图像库路径imgDir = dir([imgPath '*.jpg']); % 遍历所有jpg格式文件for i = 1:length(imgDir) % 遍历结构体就可以一一处理图片了 img = imre

python 在指定的文件夹下生成随机的测验试卷文件

#! python3 #在指定的路径中生成指定数目的测验试卷和参考答案文本,试卷内容是测验对我国28个省级行政区的省会城市的选择, #要求每份试题的试题顺序不同,不同试卷中相同试题的选项随机抽取. import random import os # 各省及其省会的字典数据 capitals = {'新疆': '乌鲁木齐', '甘肃': '兰州', '宁夏': '银川', '陕西': '西安', '青海': '西宁', '西藏': '拉萨', '贵州': '贵阳', '内蒙古': '呼和浩特',

CoreJava_线程并发(堵塞队列):在某个目录下搜索含有某keyword的文件

Java多线程编程是很考验一个程序猿水平的. 传统的WEB程序中.由于框架提供了太多的健壮性.并发性.可靠性的支持,所以我们都是将全部的注意力放到了业务实现上.我们不过依照业务逻辑的要求.不停的积累自己的代码. 由于知识,或者是经验的限制.常常出现了问题而不自知. 比如,某些比較原始的项目中.并没有使用Spring等相对来说比較灵活健壮的框架. 而是只使用Servlet来作为服务端的实现方式. 举一个简单的栗子.众所周知,当请求到了容器,容器是创建而且启动了一个Servlet线程来对当前的请求作

find命令删除当前文件夹下N天前多类文件

find . \( -name "*.gz" -o -name "*.zip" -o -name "*.cfg" \) -maxdepth 1 -mtime +2  -exec rm {} \; 说明: 删除当前文件夹(-maxdepth 1) 2天以前的(-mtime +2) 多类文件 gz zip cfg   删除 -exec rm {} \;

win7基础 cmd del+*.扩展名 删除指定文件夹下的同一类型的所有文件

系统      :Windows7注意事项  :博文内容仅供参考,不可用于其他用途. 初始状态下,原文件夹内的所有文件 cmd 窗口下的指令输入 结果展示, ------------------------------------------如果您觉得博文内容有可以优化的地方,请留下评论,我会认真思考的.

删除文件夹下各级子目录中的.svn文件

建立一个文本文件,取名为removeSvn.reg(扩展名由txt改为reg),内容如下 Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN] @="<span style="color:rgb(0,0,0);font-family:Verdana, Arial, Helvetica, sans-serif;font-size:12px;t

Linux查找文件夹下包含某字符的所有文件

Linux grep 命令用于查找文件里符合条件的字符串.grep 指令用于查找内容包含指定的范本样式的文件,如果发现某文件的内容符合所指定的范本样式,预设 grep 指令会把含有范本样式的那一列显示出来.若不指定任何文件名称,或是所给予的文件名为 -,则 grep 指令会从标准输入设备读取数据. 原文地址:https://www.cnblogs.com/toutou/p/linux_search_file.html