阻塞队列和生产者-消费模式
示例:桌面搜索
结合
程序清单5-8
程序清单5-9
程序清单5-9
程序清单7-11
程序清单7-18
程序清单7-19
import java.io.File;
import java.io.FileFilter;
import java.nio.file.Paths;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
public class IndexingService {
private static final File POISON=new File("");
private final IndexThread consumer=new IndexThread();
private final CrawlerThread producer=new CrawlerThread();
private final BlockingQueue<File> queue;
private final FileFilter fileFilter;
private final File root;
private final Map<File,String> alreadyIndexFileMap=new ConcurrentHashMap<File,String>();
public IndexingService(BlockingQueue<File> queue,FileFilter fileFilter,File root){
this.queue=queue;
this.fileFilter=fileFilter;
this.root=root;
}
class CrawlerThread extends Thread {
public void run(){
try {
crawl(root);
} catch (InterruptedException e){
e.printStackTrace();
} finally {
while (true){
try {
queue.put(POISON);
break;
} catch (InterruptedException ie){
}
}
}
}
private void crawl(File root) throws InterruptedException{
System.out.println("crawl File:"+root.getAbsolutePath());
File[] entries=root.listFiles();
if (entries!=null){
for (File entry:entries){
System.out.println("file:"+entry.getName());
if (entry.isDirectory()){
crawl(entry);
} else if (fileFilter.accept(entry)){
if (!alreadyIndexed(entry)){
queue.put(entry);
}
}
}
}
}
private boolean alreadyIndexed(File entry){
return alreadyIndexFileMap.containsKey(entry);
}
}
class IndexThread extends Thread {
public void run(){
try {
while (true){
File file=queue.take();
if (file==POISON){
break;
} else {
indexFile(file);
}
}
} catch (InterruptedException counsumed) {
}
}
private void indexFile(File file){
System.out.println("indexFile:"+file.getPath());
}
}
public void start(){
producer.start();
consumer.start();
}
public void stop(){
System.out.println("stop*******************************");
producer.interrupt();
}
public void awaitTermination() throws InterruptedException {
consumer.join();
}
public static void main(String[] args) throws InterruptedException {
BlockingQueue<File> queue=new LinkedBlockingQueue<File>(10);
FileFilter fileFilter=new FileFilter(){
public boolean accept(File file){
if (file.getName().endsWith(".doc") || file.getName().endsWith(".docx")){
return true;
}
return false;
}
};
File root=Paths.get("D:\\doc\\微云网盘").toFile();
IndexingService is=new IndexingService(queue,fileFilter,root);
is.start();
//2s
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
is.stop();
is.awaitTermination();
}
}
改成两个生产者一个消费者
import java.io.File;
import java.io.FileFilter;
import java.nio.file.Paths;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
public class IndexingServiceTwoProducerOneConsumer {
private static final File POISON1=new File("");
private static final File POISON2=new File("");
private final IndexThread consumer=new IndexThread();
private final CrawlerThread producerOne;
private final CrawlerThread producerTwo;
private final BlockingQueue<File> queue;
private final FileFilter fileFilter;
private final File root1;
private final File root2;
private final Map<File,String> alreadyIndexFileMap=new ConcurrentHashMap<File,String>();
IndexingServiceTwoProducerOneConsumer(BlockingQueue<File> queue,FileFilter fileFilter,File root1,File root2){
this.queue=queue;
this.fileFilter=fileFilter;
this.root1=root1;
this.root2=root2;
producerOne=new CrawlerThread(this.root1,POISON1);
producerTwo=new CrawlerThread(this.root2,POISON2);
}
public void start(){
producerOne.start();
producerTwo.start();
consumer.start();
}
public void stop(){
System.out.println("stop");
producerOne.interrupt();
producerTwo.interrupt();
}
public void awaitTermination() throws InterruptedException {
consumer.join();
}
public static void main(String[] args) throws InterruptedException {
BlockingQueue<File> queue=new LinkedBlockingQueue<File>(10);
FileFilter fileFilter=new FileFilter(){
public boolean accept(File file){
if (file.getName().endsWith(".doc") || file.getName().endsWith(".docx")){
return true;
}
return false;
}
};
File root1=Paths.get("D:\\doc\\dir1").toFile();
File root2=Paths.get("D:\\doc\\dir2").toFile();
IndexingServiceTwoProducerOneConsumer is=new IndexingServiceTwoProducerOneConsumer(queue,fileFilter,root1,root2);
is.start();
//2s
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
is.stop();
is.awaitTermination();
}
class CrawlerThread extends Thread {
private File root;
private File poison;
CrawlerThread(File root,File poison){
this.root=root;
this.poison=poison;
}
public void run(){
try {
crawl(root);
} catch (InterruptedException e){
} finally {
while (true){
try {
queue.put(poison);
break;
} catch (InterruptedException ie){
}
}
}
}
private void crawl(File root) throws InterruptedException{
System.out.println("crawl File:"+root.getAbsolutePath());
File[] entries=root.listFiles();
if (entries!=null){
for (File entry:entries){
System.out.println("file:"+entry.getName());
if (entry.isDirectory()){
crawl(entry);
} else if (fileFilter.accept(entry)){
if (!alreadyIndexed(entry)){
queue.put(entry);
}
}
}
}
}
private boolean alreadyIndexed(File entry){
return alreadyIndexFileMap.containsKey(entry);
}
}
class IndexThread extends Thread {
final AtomicBoolean flag1=new AtomicBoolean(false);
final AtomicBoolean flag2=new AtomicBoolean(false);
public void run(){
try {
while (true){
File file=queue.take();
if (file==POISON1){
flag1.set(true);
} else if (file==POISON2){
flag2.set(true);
} else {
indexFile(file);
}
if (flag1.get() && flag2.get()){
break;
}
}
} catch (InterruptedException counsumed) {
}
}
private void indexFile(File file){
System.out.println("indexFile:"+file.getPath());
}
}
}
改成一个生产者三个消费者
import java.io.File;
import java.io.FileFilter;
import java.nio.file.Paths;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
public class IndexingServiceOneProducerThreeConsumer {
private static final File POISON=new File("");
private final IndexThread consumer1=new IndexThread();
private final IndexThread consumer2=new IndexThread();
private final IndexThread consumer3=new IndexThread();
private final CrawlerThread producer=new CrawlerThread();
private final BlockingQueue<File> queue;
private final FileFilter fileFilter;
private final File root;
private final Map<File,String> alreadyIndexFileMap=new ConcurrentHashMap<File,String>();
public IndexingServiceOneProducerThreeConsumer(BlockingQueue<File> queue,FileFilter fileFilter,File root){
this.queue=queue;
this.fileFilter=fileFilter;
this.root=root;
}
class CrawlerThread extends Thread {
public void run(){
try {
crawl(root);
} catch (InterruptedException e){
e.printStackTrace();
} finally {
while (true){
try {
queue.put(POISON);
System.out.println("put poison ok");
break;
} catch (InterruptedException ie){
}
}
}
}
private void crawl(File root) throws InterruptedException{
System.out.println("crawl File:"+root.getAbsolutePath());
File[] entries=root.listFiles();
if (entries!=null){
for (File entry:entries){
System.out.println("file:"+entry.getName());
if (entry.isDirectory()){
crawl(entry);
} else if (fileFilter.accept(entry)){
if (!alreadyIndexed(entry)){
queue.put(entry);
}
}
}
}
}
private boolean alreadyIndexed(File entry){
return alreadyIndexFileMap.containsKey(entry);
}
}
class IndexThread extends Thread {
public void run(){
try {
while (true){
File file=queue.take();
if (file==POISON){
System.out.println("thread Name:"+Thread.currentThread().getName());
System.out.println("get poison ok");
//有n个消费者就丢n-1个
queue.put(POISON);
queue.put(POISON);
break;
} else {
indexFile(file);
}
}
} catch (InterruptedException counsumed) {
}
}
private void indexFile(File file){
System.out.println("indexFile:"+file.getPath());
}
}
public void start(){
producer.start();
consumer1.start();
consumer2.start();
consumer3.start();
}
public void stop(){
System.out.println("stop*******************************");
producer.interrupt();
}
public void awaitTermination() throws InterruptedException {
consumer1.join();
consumer2.join();
consumer3.join();
}
public static void main(String[] args) throws InterruptedException {
BlockingQueue<File> queue=new LinkedBlockingQueue<File>(10);
FileFilter fileFilter=new FileFilter(){
public boolean accept(File file){
if (file.getName().endsWith(".doc") || file.getName().endsWith(".docx")){
return true;
}
return false;
}
};
File root=Paths.get("D:\\doc\\dir").toFile();
IndexingServiceOneProducerThreeConsumer is=new IndexingServiceOneProducerThreeConsumer(queue,fileFilter,root);
is.start();
//2s
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
is.stop();
is.awaitTermination();
}
}