JAVA消费者-生产者与封锁队列。搜索工具
我试图用BlockingQueue实现一些消费者-生产者问题。为了达到某种目的,我决定编写文件搜索工具 我决定搜索机制是递归工作的,每个新目录都将有新的线程池来提高搜索速度 我的问题是,当搜索线程完成任务时,我不知道如何实现在最后停止打印线程(消费者)的机制 我试图用一些想法,比如毒丸,来实现这一点,但效果不好(在打印任何结果之前线程停止)。你知道我该怎么做吗 下面是一些代码: 搜索机制:JAVA消费者-生产者与封锁队列。搜索工具,java,multithreading,consumer,producer,Java,Multithreading,Consumer,Producer,我试图用BlockingQueue实现一些消费者-生产者问题。为了达到某种目的,我决定编写文件搜索工具 我决定搜索机制是递归工作的,每个新目录都将有新的线程池来提高搜索速度 我的问题是,当搜索线程完成任务时,我不知道如何实现在最后停止打印线程(消费者)的机制 我试图用一些想法,比如毒丸,来实现这一点,但效果不好(在打印任何结果之前线程停止)。你知道我该怎么做吗 下面是一些代码: 搜索机制: public class SearchingAlgorithm implements Runnable {
public class SearchingAlgorithm implements Runnable {
private final File file;
private BlockingQueue<File> queue;
private ExecutorService executor;
public SearchingAlgorithm(File fileName, BlockingQueue<File> queue) {
this.file = fileName;
this.queue = queue;
this.executor = Executors.newWorkStealingPool();
}
@Override
public void run() {
try {
searchDeep();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void searchDeep() throws InterruptedException {
File[] files = file.listFiles();
if (files != null) {
for (File fil : files) {
if (fil.isDirectory()) {
executor.submit(new SearchingAlgorithm(fil, this.queue));
} else {
this.queue.add(fil);
}
}
}
}
公共类搜索算法实现可运行{
私人最终文件;
私有阻塞队列;
私人遗嘱执行人;
公共搜索算法(文件名、阻止队列){
this.file=文件名;
this.queue=队列;
this.executor=Executors.newWorkStealingPool();
}
@凌驾
公开募捐{
试一试{
searchDeep();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
private void searchDeep()引发InterruptedException{
File[]files=File.listFiles();
如果(文件!=null){
用于(文件fil:文件){
if(fil.isDirectory()){
提交(新的搜索算法(fil,this.queue));
}否则{
this.queue.add(fil);
}
}
}
}
}
打印机:
public class ContainingCheckAlgorithm implements Runnable {
private BlockingQueue<File> queue;
// private ExecutorService executor;
private String keyWord;
public ContainingCheckAlgorithm(BlockingQueue<File> queue, String keyWord) {
this.queue = queue;
this.keyWord = keyWord;
// executor = Executors.newFixedThreadPool(2);
}
@Override
public void run() {
try {
printFile();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void printFile() throws InterruptedException {
while (true) {
File takeFile = queue.take();
String fileName = takeFile.getAbsolutePath()
.toLowerCase();
boolean isContainingKeyWord = fileName.contains(keyWord.toLowerCase());
if (isContainingKeyWord) {
System.out.println(takeFile.getAbsolutePath());
}
}
}
public类ContainingCheckAlgorithm实现可运行{
私有阻塞队列;
//私人遗嘱执行人;
私有字符串关键字;
public ContainingCheckAlgorithm(BlockingQueue队列,字符串关键字){
this.queue=队列;
this.keyWord=关键字;
//executor=Executors.newFixedThreadPool(2);
}
@凌驾
公开募捐{
试一试{
打印文件();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
私有void printFile()引发InterruptedException{
while(true){
File takeFile=queue.take();
字符串文件名=takeFile.getAbsolutePath()
.toLowerCase();
布尔值isContainingKeyWord=fileName.contains(关键字.toLowerCase());
if(isContainingKeyWord){
System.out.println(takeFile.getAbsolutePath());
}
}
}
}
主要测试类别:
public class MainClass {
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(2);
BlockingQueue<File> queue = new LinkedBlockingQueue<>();
File fileName = new File("C:/");
SearchingAlgorithm sa = new SearchingAlgorithm(fileName, queue);
executor.submit(sa);
ContainingCheckAlgorithm ca = new ContainingCheckAlgorithm(queue, "Slipknot");
executor.submit(ca);
executor.shutdown();
}
public类MainClass{
公共静态void main(字符串[]args)引发InterruptedException{
ExecutorService executor=Executors.newFixedThreadPool(2);
BlockingQueue=新建LinkedBlockingQueue();
文件名=新文件(“C:/”);
SearchingAlgorithm sa=新的SearchingAlgorithm(文件名、队列);
执行人提交(sa);
ContainingCheckAlgorithm ca=新的ContainingCheckAlgorithm(队列,“Slipknot”);
执行人提交(ca);
executor.shutdown();
}
}将整个工作分为两个阶段。在第一阶段,如果队列为空,SearchingAlgorithm的工作和ContainingCheckAlgorithm将等待新作业。在第二阶段,所有SearchingAlgorithm实例完成,如果发现队列为空,ContainingCheckAlgorithm将退出。要发现队列是否为空,ContainingCheckAlgorithm使用queue.poll(超时)而不是queue.take()
您不需要为每个搜索算法创建新的线程池。正如您所说,我尝试这样做: 搜索算法与其他搜索算法共享线程池 搜索:
public class MainClass {
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newCachedThreadPool();
BlockingQueue<File> queue = new LinkedBlockingQueue<>();
CountDownLatch latch = new CountDownLatch(1);
File fileName = new File("C:/");
SearchingAlgorithm sa = new SearchingAlgorithm(fileName, queue, executor);
executor.submit(sa);
ContainingCheckAlgorithm ca = new ContainingCheckAlgorithm(queue, "Slipknot", latch);
executor.submit(ca);
latch.await();
executor.shutdown();
}
公共类搜索算法实现可运行{
私人最终文件;
私有阻塞队列;
私人遗嘱执行人;
公共搜索算法(文件名、阻止队列、执行器服务执行器){
this.file=文件名;
this.queue=队列;
this.executor=执行人;
}
@凌驾
公开募捐{
试一试{
searchDeep();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
private void searchDeep()引发InterruptedException{
File[]files=File.listFiles();
如果(文件!=null){
用于(文件fil:文件){
if(fil.isDirectory()){
executor.submit(新搜索算法(fil,this.queue,executor));
}否则{
this.queue.add(fil);
}
}
}
}
现在ContainingCheckAlgorith需要与main类共享CountDownLatch,因为我需要一些机制来关闭main类中的线程池。正如你所说,它使用池(超时),我的线程最终完成了任务
检查
public class ContainingCheckAlgorithm implements Runnable {
private BlockingQueue<File> queue;
private String keyWord;
private CountDownLatch latch;
public ContainingCheckAlgorithm(BlockingQueue<File> queue, String keyWord, CountDownLatch latch) {
this.queue = queue;
this.keyWord = keyWord;
this.latch = latch;
}
@Override
public void run() {
try {
printFile();
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void printFile() throws InterruptedException {
File takeFile;
while ((takeFile = queue.poll(1, TimeUnit.SECONDS)) != null) {
String fileName = takeFile.getName()
.toLowerCase();
boolean isContainingKeyWord = fileName.contains(keyWord.toLowerCase());
if (isContainingKeyWord) {
System.out.println(takeFile.getAbsolutePath());
}
}
}
public类ContainingCheckAlgorithm实现可运行{
私有阻塞队列;
私有字符串关键字;
私人倒计时闩锁;
public ContainingCheckAlgorithm(BlockingQueue队列、字符串关键字、CountDownLatch闩锁){
this.queue=队列;
this.keyWord=关键字;
this.latch=闩锁;
}
@凌驾
公开募捐{
试一试{
打印文件();
倒计时();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
私有void printFile()引发InterruptedException{
文件takeFile;
而((takeFile=queue.poll(1,TimeUnit.SECONDS))!=null){
字符串文件名=takeFile.getName()
.toLowerCase();
布尔值isContainingKeyWord=fileName.contains(关键字.toLowerCase());
if(isContainingKeyWord){
System.out.println(takeFile.getAbsolutePath());
}
}
}
MAIN:
public class MainClass {
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newCachedThreadPool();
BlockingQueue<File> queue = new LinkedBlockingQueue<>();
CountDownLatch latch = new CountDownLatch(1);
File fileName = new File("C:/");
SearchingAlgorithm sa = new SearchingAlgorithm(fileName, queue, executor);
executor.submit(sa);
ContainingCheckAlgorithm ca = new ContainingCheckAlgorithm(queue, "Slipknot", latch);
executor.submit(ca);
latch.await();
executor.shutdown();
}
public类MainClass{
公共静态void main(字符串[]args)引发InterruptedException{
ExecutorService executor=Executors.newCachedThreadPool();
BlockingQueue=新建LinkedBlockingQueue();
CountDownLatch闩锁=新的CountDownLatch(1);
文件名=新文件(“C:/”);
SearchingAlgorithm sa=新的SearchingAlgorithm(文件