And more code (no need to wait)

Posted Fri, 23 Nov 2007 09:53:18 GMT

Thanks to Yuri for pointing out that you don’t need to wait until all the results are done to start processing them. Here, we’ve only got integers, but in reality it is likely that the individual results will be big and meaningful and actually take some time to interpret or do something with. To start working on them as soon as each one is ready, we use CompletionService:


public class ParallelCompletionCounter {
    public int countWordsAsSoonAsFileFinishes(List files) {
        CompletionService completionService = new ExecutorCompletionService(Executors.newFixedThreadPool(4));
        for(final File file : files) {
            Callable counter = new Callable() {
                public Integer call() {
                    System.out.println("Starting file " + file.getName() + " at " + System.currentTimeMillis());
                    int time = 500;
                    if (file.getName().contains("304")) {
                        time = 5000;
                    }
                    try {
                        Thread.sleep(time);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    WordCounter counter = new WordCounter();
                    int count =  counter.count(file);
                    System.out.println("Done file " + file.getName() + " at " + System.currentTimeMillis());
                    return count;
                }
            };
            completionService.submit(counter);
        }
        try {
            int totalCount = 0;
            for (int i = 0; i<4; i++) {
                totalCount += completionService.take().get();
                System.out.println("Added File Count");
            }
            return totalCount;
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        ParallelCompletionCounter counter = new ParallelCompletionCounter();
        List files = new ArrayList(args.length);
        for (String filename : args) {
            files.add(new File(filename));
        }
        System.out.println("Total word count is " + counter.countWordsAsSoonAsFileFinishes(files));
        System.out.println("Total elapsed time " + (System.currentTimeMillis() - start));
    }   
}

no comments | no trackbacks

More code

Posted Thu, 22 Nov 2007 13:06:12 GMT

I’ve been exploring the java.util.concurrent package, and just thought I post some more code:

public class ParallelCounter {

    public int countWords1(List files) {
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        List> counters = new ArrayList>();
        for(final File file : files) {
            counters.add(new Callable() {
                public Integer call() {
                    System.out.println("Starting file " + file.getName() + " at " + System.currentTimeMillis());
                    WordCounter counter = new WordCounter();
                    int count =  counter.count(file);
                    System.out.println("Done file " + file.getName() + " at " + System.currentTimeMillis());
                    return count;
                }
            });
        }
        try {
            List> results = executorService.invokeAll(counters);
            int totalCount = 0;
            for (Future future : results) {
                totalCount += future.get();
            }
            return totalCount;
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        ParallelCounter counter = new ParallelCounter();
        List files = new ArrayList(args.length);
        for (String filename : args) {
            files.add(new File(filename));
        }
        System.out.println("Total word count is " + counter.countWords1(files));
        System.out.println("Total elapsed time " +
(System.currentTimeMillis() - start));
    }
}

1 comment | no trackbacks

The five philosophers

Posted Tue, 20 Nov 2007 09:54:00 GMT

Here’s my little implementation of the five philosophers problem.

The chopstick:

package philosophers;

public class Chopstick {

    private int number;

    public Chopstick(int number) {
        this.number = number;
    }
    public int getNumber() {
        return number;
    }
}

The philosopher:

package philosophers;

public class Philosopher implements Runnable {

    private int number;

    private Chopstick leftChopstick;

    private Chopstick rightChopstick;

    public Philosopher(int number, Chopstick leftChopstick,
            Chopstick rightChopstick) {
        this.number = number;
        this.leftChopstick = leftChopstick;
        this.rightChopstick = rightChopstick;
    }

    private void eat(int time) {
        synchronized (leftChopstick) {
            System.out.println("Philosopher " + this.number
                    + " took chopstick " + leftChopstick.getNumber()
                    + " from the left.");
            synchronized (rightChopstick) {
                System.out.println("Philosopher " + this.number
                        + " took chopstick " + rightChopstick.getNumber()
                        + " from the right.");
                try {
                    System.out.println("Philosopher " + this.number
                            + " is eating...");
                    Thread.sleep(time);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    private void think(int time) {
        try {
            System.out.println("Philosopher " + this.number + " is thinking...");
            Thread.sleep(time);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public void run() {
        while (true) {
            think(1);
            eat(1);
        }
    }

}

And, bringing them all together, the Table:

package philosophers;

public class Table {

    /**
     * Chopstick 0 is on the left of phylosopher 0
     */
    private Chopstick[] chopsticks;

    private Philosopher[] philosophers;

    public void build(int numberOfSeats) {
        for (int i = 0; i < numberOfSeats; i++) {
            chopsticks[i] = new Chopstick(i);
        }
        for (int i = 0; i < numberOfSeats; i++) {
            philosophers[i] = new Philosopher(i, chopsticks[i],
                    chopsticks[i < numberOfSeats - 1 ? i + 1 : 0]);
        }
    }

    public Table(int numberOfSeats) {
        chopsticks = new Chopstick[numberOfSeats];
        philosophers = new Philosopher[numberOfSeats];
        build(numberOfSeats);
    }

    public void start() {
        System.out.println("Chopstick 0 is on the left of philosopher 0");
        for (Philosopher philosopher : philosophers) {
            new Thread(philosopher).start();
        }
    }

    public static void main (String[] args) {
        new Table(5).start();
    }
}

Deadlocks pretty quickly with the numbers as they are here.

no comments | no trackbacks

Home

Who's George?

Recent entries