Java多线程编程是很考验一个程序猿水平的。

传统的WEB程序中。由于框架提供了太多的健壮性、并发性、可靠性的支持,所以我们都是将全部的注意力放到了业务实现上。我们不过依照业务逻辑的要求。不停的积累自己的代码。

由于知识,或者是经验的限制。常常出现了问题而不自知。

比如,某些比較原始的项目中。并没有使用Spring等相对来说比較灵活健壮的框架。

而是只使用Servlet来作为服务端的实现方式。

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

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

以下是在核心技术上的一个非常好的。能够用来研究堵塞队列的Demo。目的是用于在某一个给定的目录以下。搜索全部含有某个keyword的文件,这中功能在非常多编辑器下都有详细的实现。比如UE。

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

  1. import java.io.File;
  2. import java.io.FileInputStream;
  3. import java.io.IOException;
  4. import java.util.Scanner;
  5. import java.util.concurrent.ArrayBlockingQueue;
  6. import java.util.concurrent.BlockingQueue;
  7.  
  8. public class BlockingQueueTest {
  9. public static void main(String[] args) {
  10. Scanner in = new Scanner(System.in);
  11. System.out.println("Enter base directory(eg. /usr/local/jdk1.6.0/src)");
  12. String directory = in.nextLine();
  13. System.out.println("Enter keyword(e.g. volatile):");
  14. String keyword = in.nextLine();
  15.  
  16. final int FILE_QUEUE_SIZE=10;
  17. final int SEARCH_THREADS =100;
  18.  
  19. BlockingQueue<File> queue = new ArrayBlockingQueue<File>(FILE_QUEUE_SIZE);
  20.  
  21. FileEnumerationTask enumerator = new FileEnumerationTask(queue,new File(directory));
  22. new Thread(enumerator).start();
  23. for(int i=1;i<=SEARCH_THREADS;i++){
  24. new Thread(new SearchTask(queue,keyword)).start();
  25. }
  26. }
  27. }
  28.  
  29. class FileEnumerationTask implements Runnable{
  30.  
  31. public FileEnumerationTask(BlockingQueue<File> queue,File startingDirectory){
  32. this.queue=queue;
  33. this.startingDirectory = startingDirectory;
  34. }
  35. @Override
  36. public void run() {
  37. try{
  38. enumerate(startingDirectory);
  39. queue.put(DUMMY);
  40. }catch(InterruptedException e){
  41. }
  42. }
  43. public void enumerate(File directory)throws InterruptedException{
  44. File[] files = directory.listFiles();
  45. for(File file : files){
  46. if(file.isDirectory())enumerate(file);
  47. else queue.put(file);
  48. }
  49. }
  50. public static File DUMMY = new File("");
  51.  
  52. private BlockingQueue<File> queue;
  53. private File startingDirectory;
  54. }
  55.  
  56. class SearchTask implements Runnable{
  57. public SearchTask(BlockingQueue<File> queue,String keyword){
  58. this.queue = queue;
  59. this.keyword = keyword;
  60. }
  61. @Override
  62. public void run() {
  63. try {
  64. boolean done = false;
  65. while(!done){
  66. File file = queue.take();
  67. if(file==FileEnumerationTask.DUMMY){
  68. queue.put(file);
  69. done=true;
  70. }
  71. else {
  72. search(file);
  73. }
  74. }
  75. }catch(IOException e){
  76.  
  77. }
  78. catch (InterruptedException e) {
  79. }
  80. }
  81.  
  82. private void search(File file)throws IOException{
  83. Scanner in = new Scanner(new FileInputStream(file));
  84. int lineNumber = 0;
  85. while(in.hasNextLine()){
  86. lineNumber++;
  87. String line = in.nextLine();
  88. if(line.contains(keyword))System.out.printf("%s:%d:%s%n",file.getPath(),lineNumber,line);
  89. }
  90. in.close();
  91. }
  92.  
  93. private BlockingQueue<File> queue;
  94. private String keyword;
  95. }

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

  1. FileFilter 遍历某个目录下文件名含有某个字符的文件

    由于IIS版本的升级,造成了文件名中含有“+”的特殊字符的文件(多数是图片)在网页中不能被访问,于是必须查找当前目录下含有多少这样的文件,从而制定最佳的解决方案. 废话少说,直接上核心代码: publ ...

  2. 位于/var/log目录下的20个Linux日志文件

    位于/var/log目录下的20个Linux日志文件[译] from:http://buptguo.com/2014/01/16/linux-var-log-files/ 原文地址:20 Linux ...

  3. QT工程构建目录下,将生成的中间文件和可执行文件分离

    在QT工程中,当我们选择了构建目录后,编译生成程序后,总会发现在debug目录下会有混淆着各类文件,如下图 很多时候,我们又仅仅只需要可执行文件或者自定义的动态链接库.如下图 当然,如果不觉得麻烦,有 ...

  4. Java线程:堵塞队列与堵塞栈

    一.堵塞队列 Java定义了堵塞队列的接口java.util.concurrent.BlockingQueue,堵塞队列是一个指定长度的队列,当试图向队列中添加元素而队列已满,或者是想从队列移出元素而 ...

  5. Ztree的初步使用--checkbox--指定目录下搜索子节点

    这里记录一下zTree的check的使用 首先 <%@ Page Language="C#" AutoEventWireup="true" CodeBeh ...

  6. copy指定目录下包括子目录中所有的文件

    #include <windows.h> #include <iostream> #include <string> using namespace std; DW ...

  7. Java Web中提交表单之后跳转到WebContent目录下的子目录里的jsp文件

    最近在做一个系统,需要完成登录动能进行跳转到另一个页面.在这个项目里面,我把 jsp,css,js文件都统一放在 WebContent 目录下的一个 WebPage 里面. 按照以前的习惯,写好了 s ...

  8. IO流-递归遍历目录下指定后缀名结尾的文件名称

    /* *自定义遍历目录下指定后缀名结尾文件的名称的方法: * * param file:指定目录 name:指定后缀名 */ 1 public static void FileName(File fi ...

  9. Linux查找目录下的按时间过滤的文件

    在维护项目中,有时会指定都一些条件进行过滤文件,并对该批文件进行操作:这时我们将使用shell命令进行操作:直接上代码 #!/bin/sh #BEGIN #`find ./ ! -name " ...

随机推荐

  1. Mysql安装过程(linux:2.6.18-194.el5,Mysql:)

    1.安装[root@RAC2 mysql]# rpm -ivh MySQL-server-5.6.12-2.rhel5.x86_64.rpm Preparing... ################ ...

  2. POJ 3122 Pie 二分枚举

    题目:http://poj.org/problem?id=3122 这个题就好多了,没有恶心的精度问题,所以1A了.. #include <stdio.h> #include <ma ...

  3. 补充一下我对 POJ 3273 的理解,这肯定是我一生写的最多的题解。。。

    题目:http://poj.org/problem?id=3273 当分成的组数越多,所有组的最大值就会越小或不变,这一点不难证明:    如果当前分成了group组,最大值是max,那么max的这一 ...

  4. OC修饰词 - 内存管理

    <招聘一个靠谱的 iOS>—参考答案(上) 说明:面试题来源是微博@我就叫Sunny怎么了的这篇博文:<招聘一个靠谱的 iOS>,其中共55题,除第一题为纠错题外,其他54道均 ...

  5. 解决ubuntu侧边栏固定应用单击无反应的问题

    Linux下有些绿色软件,不需要安装就可以双击启动,但有些程序在打开后直接在 Launcher 中右键选择 Lock to Launcher ,但是,有时候单击图标后并未启动应用,下面给出解决方法. ...

  6. uva 11437 - Triangle Fun

    计算几何: 直线交点: #include<cstdio> using namespace std; struct node { double x,y; node(,):x(x),y(y){ ...

  7. python代码优化技巧

    转自:http://www.douban.com/group/topic/31478102/ 这个资料库还有些不错的好文章: http://www.ibm.com/developerworks/cn/ ...

  8. vs2010自带的报表

    本例用来显示Northwind中的order details表中的数据交分组 1.建立一WinForm程序,并建立一数据库连接,选择order details表,此时会自动建立一个xsd的数据集类,如 ...

  9. 时区 : America/Mexico_City 中文:美国中部时间(墨西哥城) 的夏令时

    方法: (参数为: TimeZone timeZone = TimeZone.getTimeZone("America/Mexico_City"); private static ...

  10. ArcGIS_系列中文教程

    转自:http://www.cnblogs.com/gispeng/archive/2008/04/15/1154212.html  ArcGIS_系列中文教程 如链接有问题请在留言中说明ArcGIS ...