CoreJava_线程并发(堵塞队列):在某个目录下搜索含有某keyword的文件
Java多线程编程是很考验一个程序猿水平的。
传统的WEB程序中。由于框架提供了太多的健壮性、并发性、可靠性的支持,所以我们都是将全部的注意力放到了业务实现上。我们不过依照业务逻辑的要求。不停的积累自己的代码。
由于知识,或者是经验的限制。常常出现了问题而不自知。
比如,某些比較原始的项目中。并没有使用Spring等相对来说比較灵活健壮的框架。
而是只使用Servlet来作为服务端的实现方式。
举一个简单的栗子。众所周知,当请求到了容器,容器是创建而且启动了一个Servlet线程来对当前的请求作出对应,这个时候。Servlet中的成员变量就会受到多线程的影响。这样,在Servlet中书写成员变量代码就会变得很的危急。由于毕竟不是一个线程安全的设计。多线程的同步、相互排斥、竞争、配合以及线程的中断等成了我们在编码过程中。很注意的一个知识点。
Java核心技术中。说到怎样对多线程进行并发控制:首先:建议使用堵塞队列。堵塞队列是由专业的线程安全的一个数据结构。我们在这个上面进行编程,就如同站在巨人的肩膀上,至于非常多低层的实现就是他们去考虑的事情了。其次,假设想自己控制多线程并发的时候,尽可能的推荐使用synchronizedkeyword,synchronizedkeyword实际上就是等同于ReentrantLock或者读写锁的实现,只是语法更加简洁。更不太easy出错。FINALLY。最后,假设有充足的理由的时候,才会推荐使用ReentrantLock或者ReentrantReadWriteLock、ReadLock、WriteLock以及其对应的condition条、volatile等等,由于这些太过于低层,并且依照java一贯的实现编码逻辑,我们仅仅须要知道某一个控制线程并发数据结构的存在就能够了。
以下是在核心技术上的一个非常好的。能够用来研究堵塞队列的Demo。目的是用于在某一个给定的目录以下。搜索全部含有某个keyword的文件,这中功能在非常多编辑器下都有详细的实现。比如UE。
功能的实现方式大概是这种:生产者线程,将当前给定的目录以下的全部的文件,放到堵塞队列中(功能实现中使用了递归),最后,放置一个空的文件,作为一个标志。类似于一个信号灯的样子。创建了非常多的消费者线程,从堵塞队列中,循环获取一个文件,然后进行逐行遍历,假设其中含有keyword则打印。跳出循环的条件是看到了消费者线程放置的信号灯。功能的实现将并发依赖于一个并发的数据结构。非常值得去借鉴。
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_线程并发(堵塞队列):在某个目录下搜索含有某keyword的文件的更多相关文章
- FileFilter 遍历某个目录下文件名含有某个字符的文件
由于IIS版本的升级,造成了文件名中含有“+”的特殊字符的文件(多数是图片)在网页中不能被访问,于是必须查找当前目录下含有多少这样的文件,从而制定最佳的解决方案. 废话少说,直接上核心代码: publ ...
- 位于/var/log目录下的20个Linux日志文件
位于/var/log目录下的20个Linux日志文件[译] from:http://buptguo.com/2014/01/16/linux-var-log-files/ 原文地址:20 Linux ...
- QT工程构建目录下,将生成的中间文件和可执行文件分离
在QT工程中,当我们选择了构建目录后,编译生成程序后,总会发现在debug目录下会有混淆着各类文件,如下图 很多时候,我们又仅仅只需要可执行文件或者自定义的动态链接库.如下图 当然,如果不觉得麻烦,有 ...
- Java线程:堵塞队列与堵塞栈
一.堵塞队列 Java定义了堵塞队列的接口java.util.concurrent.BlockingQueue,堵塞队列是一个指定长度的队列,当试图向队列中添加元素而队列已满,或者是想从队列移出元素而 ...
- Ztree的初步使用--checkbox--指定目录下搜索子节点
这里记录一下zTree的check的使用 首先 <%@ Page Language="C#" AutoEventWireup="true" CodeBeh ...
- copy指定目录下包括子目录中所有的文件
#include <windows.h> #include <iostream> #include <string> using namespace std; DW ...
- Java Web中提交表单之后跳转到WebContent目录下的子目录里的jsp文件
最近在做一个系统,需要完成登录动能进行跳转到另一个页面.在这个项目里面,我把 jsp,css,js文件都统一放在 WebContent 目录下的一个 WebPage 里面. 按照以前的习惯,写好了 s ...
- IO流-递归遍历目录下指定后缀名结尾的文件名称
/* *自定义遍历目录下指定后缀名结尾文件的名称的方法: * * param file:指定目录 name:指定后缀名 */ 1 public static void FileName(File fi ...
- Linux查找目录下的按时间过滤的文件
在维护项目中,有时会指定都一些条件进行过滤文件,并对该批文件进行操作:这时我们将使用shell命令进行操作:直接上代码 #!/bin/sh #BEGIN #`find ./ ! -name " ...
随机推荐
- MOS管体二极管的作用
这里有两种解释: 1.mos管本身自带有寄生二极管,作用是防止VDD过压的情况下,烧坏mos管,因为在过压对MOS管造成破坏之前,二极管先反向击穿,将大电流直接到地,从而避免MOS管被烧坏. 2.防止 ...
- Areas(区域)
Areas(区域) 原文:Areas作者:Dhananjay Kumar 和 Rick Anderson翻译:耿晓亮(Blue)校对:许登洋(Seay) Areas 是 ASP.NET MVC 用来将 ...
- C# RichTextBox 获取当前显示部分的文字
int start = richTextBox1.GetCharIndexFromPosition(new Point(0, 0)); int end = richTextBox1.GetCharIn ...
- rabbitmq 测试
--*-- import pika import datetime connection = pika.BlockingConnection(pika.ConnectionParameters( 'l ...
- 【JavaScript】JavaScript函数的参数
要访问js函数中传入的所有参数,可以使用特殊的arguments变量.但是虽然可以像访问数组一样从arguments变量中读取参数,但arguments并非真正的数组.例如,arguments没有pu ...
- android中viewPager+fragment实现的屏幕左右切换(进阶篇)
Fragment支持在不同的Activity中使用并且可以处理自己的输入事件以及生命周期方法等.可以看做是一个子Activity. 先看一下布局: 1 <LinearLayout xmlns:a ...
- 【Ecmall】ECMall2.x模板制作入门系列(认识ECMall模板)
ECMall2.x模板制作入门系列之1(认识ECMall模板) 从ECMall2.0全新架构发布以来,随着版本的不断更新,ECMall已经逐渐走向一个稳定时期,是时候整理一些实用教程了.下面给大家带来 ...
- 又爱又恨的BOOTSTRAP
搞本书,看了一天,确实,,UIKIT比它好用... 但,艺多不压身吧. 今天自己抄了个大概的,不用其它插件,,但那手风琴,真的找了很多,没有中意的... <!DOCTYPE html> & ...
- Android 使用SharedPreference来进行软件配置的存取
我们在安卓开发的时候不免需要记录用户键入的一些信息,比如账号和密码,用户使用软件的次数,上次打开软件的时间等等,为了保存这些配置,我们可以使用SharedPreference类保存他们. //使用Sh ...
- Jquery 获取表单值如input,select等方法
1 if($("input[name=item][value='val']").attr('checked')==true) //判断是否已经打勾 name即控件name属性,va ...