2

当我测试一个简单的生产者/消费者示例时,我得到了一个非常奇怪的结果,如下所示。

  1. 如果我使用 main() 来测试以下代码,我将得到正确且预期的结果。
  2. 但我只能正确获取第一个目录,其余的作品被 JUnit 删除了。

确切的原因是什么?

工作代码

import java.io.File;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import org.junit.Test;

public class TestProducerAndConsumer {

    public static void main(String[] args) {
        BlockingQueue<File> queue = new LinkedBlockingQueue<File>(1000);

        new Thread(new FileCrawler(queue, new File("C:\\"))).start();
        new Thread(new Indexer(queue)).start();
    }
}

错误代码:

import java.io.File;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import org.junit.Test;

public class TestProducerAndConsumer {

    @Test
    public void start2() {
        BlockingQueue<File> queue = new LinkedBlockingQueue<File>(1000);

        new Thread(new FileCrawler(queue, new File("C:\\"))).start();
        new Thread(new Indexer(queue)).start();
    }
}

其他功能代码:

import java.io.File;
import java.util.Arrays;
import java.util.concurrent.BlockingQueue;

public class FileCrawler implements Runnable {
    private final BlockingQueue<File> fileQueue;
    private final File root;
    private int i = 0;

    public FileCrawler(BlockingQueue<File> fileQueue, File root) {
        this.fileQueue = fileQueue;
        this.root = root;
    }

    @Override
    public void run() {
        try {
            craw(root);
        } catch (InterruptedException e) {
            System.out.println("shit!");
            e.printStackTrace();
            Thread.currentThread().interrupt();
        }

    }

    private void craw(File file) throws InterruptedException {
        File[] entries = file.listFiles();
        //System.out.println(Arrays.toString(entries));
        if (entries != null && entries.length > 0) {
            for (File entry : entries) {
                if (entry.isDirectory()) {
                    craw(entry);
                } else {
                    fileQueue.offer(entry);
                    i++;
                    System.out.println(entry);
                    System.out.println(i);
                }
            }
        }

    }

    public static void main(String[] args) throws InterruptedException {
        FileCrawler fc = new FileCrawler(null, null);
        fc.craw(new File("C:\\"));
        System.out.println(fc.i);
    }

}




import java.io.File;
import java.util.concurrent.BlockingQueue;

public class Indexer implements Runnable {

    private BlockingQueue<File> queue;

    public Indexer(BlockingQueue<File> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            while (true) {
                indexFile(queue.take());
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    private void indexFile(File file) {
        System.out.println("Indexing ... " + file);

    }
}
4

1 回答 1

3

一旦测试完成,Junit 可能会允许 JVM 和线程终止——因此您的线程无法完成工作。

尝试等待线程“加入”:

Thread crawlerThread = new Thread(new FileCrawler(queue, new File("C:\\")));
Thread indexerThread = new Thread(new Indexer(queue));
crawlerThread.start();
indexerThread.start();
// 
// wait for them to finish.
crawlerThread.join();
indexerThread.join();

这应该会有所帮助。

.. 可能出错的另一件事是日志输出(通过 Log4J)有时会在执行结束时被截断;冲洗和暂停可以提供帮助。但我认为这不会影响你。

于 2013-05-05T11:31:57.607 回答