Book: Psychology of Computer Programming

Posted Sun, 17 Feb 2008 21:02:56 GMT

If you haven’t read this, read it now - http://www.bookdepository.co.uk/WEBSITE/WWW/WEBPAGES/showbook.php?id=0932633420

I can not believe I have only found this book recently - it’s been around for 25 years! How good is that for a computer book. I reckon that’s because programming is not as much about technologies as it is about human behaviour, thought and self-awareness.

Gerry Weinberg explains, in his extremely effective and efficient style, familiar from Secrets of Consulting, what this stuff is all about.

Thanks to Ludo, on whose desk I spotted it. When you read it, pass it on - it can only do good to everyone who reads it and their immediate surrounding.

no comments | no trackbacks

Java enums over IIOP

Posted Sun, 17 Feb 2008 18:42:00 GMT

If you pass an enum argument over IIOP, the value in the deserialised object on the server has very strange properties. Here’s what I observed (someEnum is the deserialised object on the server):

someEnum = null
someEnum.name() = null
someEnum.toString() = null
(someEnum == null) = false

Clearly a fairly useless instance for any possible purpose. It’s null, but not quite. It has no value and can not be meaningfully compared.

You can’t work around it with Externalizable, because the immutable enum can not modify itself, and for the same (perfectly valid) reason write/readObject are useless.

This was reported in May 2005 - here - http://bugs.sun.com/bugdatabase/viewbug.do?bugid=6277781

The last comment on that entry, made in Aug 2007 says: “btw, is someone working on that?…”.

Seems either people who use Java 5 and later do not use IIOP and vice versa, or you’d have thought someone would have done something by now….

Any super-clever ideas for a workaround are most welcome.

“Don’t use enums” and “don’t use IIOP” do not count as super-clever on this occasion.

no comments | no trackbacks

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

Older posts: 1 2 3 4 ... 14

Home

Who's George?

Recent entries