Producer-Consumer Pattern Example

업데이트:

자바 병렬 프로그래밍 <브라이언 게츠 외 5인> 책을 읽고 정리했습니다.

FileCrawler

  • Producer 역할
  • 디스크에 들어 있는 디렉토리 계층 구조를 따라가면서 검색 대상 파일을 작업 큐에 쌓는다

Indexer

  • Consumer 역할
  • 작업 큐에 있는 파일 이름을 뽑아ㅐ 해당 파일의 내용을 색인한다

FileCrawler

package concurrency;

import java.io.File;
import java.io.FileFilter;
import java.util.concurrent.BlockingDeque;

public class FileCrawler implements Runnable {
    private final BlockingDeque<File> fileQueue;
    private final FileFilter fileFilter;
    private final File root;

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

    @Override
    public void run() {
        try {
            crawl(root);
        } catch (InterruptedException ie) {
            Thread.currentThread().interrupt();
        }
    }

    private void crawl(File root) throws InterruptedException {
        File[] entries = root.listFiles();
        if (entries != null) {
            for (File entry : entries) {
                if (entry.isDirectory()) {
                    crawl(entry);
                } else if (!alreadyIndexed(entries)) {
                    fileQueue.put(entry);
                }
            }
        }
    }
}

Indexer

package concurrency;

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

public class Indexer implements Runnable {
    private final BlockingQueue<File> fileQueue;

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

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

    public static void startIndexing(File[] roots) {
        int BOUND = 100;
        int N_CONSUMERS = 3;

        BlockingQueue<File> queue = new LinkedBlockingQueue<>(BOUND);
        FileFilter filter = pathname -> true;

        for (File root : roots) {
            new Thread(new FileCrawler(queue, filter, root)).start();
        }

        for (int i = 0; i < N_CONSUMERS; i++) {
            new Thread(new Indexer(queue)).start();
        }
    }
}

계속해서 읽어나가는 중..

댓글남기기