Thursday, September 25, 2008

Hamlet D'Arcy's "Declarative Synchronization with Java 5's ReadWriteLock"

Hamlet D'Arcy posts on declarative synchronization with Java combining JDK4 proxies, JDK5 concurrency and Groovy, a very slick conjunction of technologies. Plus Hamlet is a cool name.

UPDATE: It is simple enough to translate the Groovy into pure Java (with a class rename and factory method along the way):

public class ReentrantHandler
        implements InvocationHandler {
    private final ReadWriteLock lock = new ReentrantReadWriteLock();

    private final Object target;

    public static <T> T newReentrantProxy(final Class<T> itf, final T impl) {
        return itf.cast(newProxyInstance(impl.getClass().getClassLoader(),
                new Class<?>[]{itf}, new ReentrantHandler(impl)));
    }

    private ReentrantHandler(final Object target) {
        this.target = target;
    }

    public Object invoke(final Object proxy, final Method method,
            final Object[] args) {
        try {
            final Method targetMethod = target.getClass().getMethod(
                    method.getName(), method.getParameterTypes());

            if (targetMethod.isAnnotationPresent(WithReadLock.class)) {
                lock.readLock().lock();
                try {
                    return targetMethod.invoke(target, args);
                } finally {
                    lock.readLock().unlock();
                }
            } else if (targetMethod.isAnnotationPresent(WithWriteLock.class)) {
                lock.writeLock().lock();
                try {
                    return targetMethod.invoke(target, args);
                } finally {
                    lock.writeLock().unlock();
                }
            } else {
                return targetMethod.invoke(target, args);
            }
        } catch (final Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}

Tuesday, September 23, 2008

Finding cyclic calls with state: Google Collections

I found a clever way to detect cyclic calls in Google Collections:

  private static class MemoizingSupplier<T>
      implements SerializableSupplier<T> {
    private final Supplier<T> delegate;
    private MemoizationState state = MemoizationState.NOT_YET;
    private T value;

    public MemoizingSupplier(Supplier<T> delegate) {
      this.delegate = delegate;
    }
    public T get() {
      switch (state) {
        case NOT_YET:
          state = MemoizationState.COMPUTING;
          try {
            value = delegate.get();
          } finally {
            state = MemoizationState.NOT_YET;
          }
          state = MemoizationState.DONE;
          break;
        case COMPUTING:
          throw new CyclicDependencyException();
      }
      return value;
    }
    private static final long serialVersionUID = 1138306392412025275L;
  }

I doubt it is original, but I have not run across this combining of cycle detection with memoizing before. That probably says more about me than Google.

Thursday, September 11, 2008

Serializing an interface into a work queue

Using the work queue idiom and JDK4 proxies, one can automate serializing calls into an interface:

public class FacadeFactory<T> {
   private final Class<T> interfaz;
   private final BlockingQueue<Frame> queue;
   private final ExecutorService pool;

   public FacadeFactory(final Class<T> interfaz,
           final BlockingQueue<Frame> queue, final ExecutorService pool) {
       this.interfaz = interfaz;
       this.queue = queue;
       this.pool = pool;
   }

   public T facade(final T delegate) {
       pool.submit(new Callable<Void>() {
           public Void call() {
               final List<Frame> work = new ArrayList<Frame>();

               for (; ;) {
                   try {
                       work.add(queue.take());
                   } catch (final InterruptedException e) {
                       currentThread().interrupt();
                       return null;
                   }
                   queue.drainTo(work);

                   for (final Frame frame : work)
                       frame.apply(delegate);

                   work.clear();
               }
           }
       });


       return interfaz.cast(newProxyInstance(interfaz.getClassLoader(),
               new Class<?>[]{interfaz}, new InvocationHandler() {
                   public Object invoke(final Object proxy,
                           final Method method, final Object[] args)
                           throws Throwable {
                       queue.offer(new Frame(method, args));

                       return null;
                   }
               }));
   }

   public class Frame {
       final Method method;
       final Object[] args;

       private Frame(final Method method, final Object[] args) {
           this.method = method;
           this.args = args;
       }

       private void apply(final T delegate) {
           try {
               method.invoke(delegate, args);
           } catch (final IllegalAccessException e) {
               throw new Error(e);
           } catch (final InvocationTargetException e) {
               throw new Error(e);
           }
       }
   }
}

In other words, turn calls against an interface spread across several threads into a sequence of single-threaded calls on a worker thread.

My motivation is isolating legacy non-thread-safe code in a threaded program without refactoring either the callers or the legacy code. I use a wrapper instead to make the many-threads to one-thread fix.

Sample use:

public class FacadeFactoryTest {
    private FacadeFactory<Bob> factory;

    @Before
    public void setUp() {
        factory = new FacadeFactory<Bob>(Bob.class,
                new ArrayBlockingQueue<FacadeFactory<Bob>.Frame>(1),
                newSingleThreadExecutor());
    }

    @Test(timeout = 100L)
    public void testFoo()
            throws InterruptedException {
        final CountDownLatch latch = new CountDownLatch(1);

        factory.facade(new Bob() {
            public void dooby() {
                latch.countDown();
            }
        }).dooby();

        latch.await();
    }

    public static interface Bob {
        void dooby();
    }
}

Tuesday, August 05, 2008

Java.next?

Stuart Halloway posts a clever take on a successor to Java: all of the above. This is part one of a series based on his No Fluff, Just Stuff presentation.

His post also gave me a quick look at side-by-side syntax for common features. I was surprised that out of clojure, jruby, groovy and scala, I preferred groovy.

Thursday, July 31, 2008

Progress in Functional Java

I have been happy lately to see the progress in Functional Java. A project truly arrives when it becomes the inspiration for other clever ideas. Witness Lazy Error Handling in Java, Part 1: The Thrower Functor.

Every few days comes another fun bit of functional programming creeping its way in to my workaday language, Java. Current wish list item: the fj team deploys to a public Maven repository so I can just say:

<dependency>
    <groupId>fj</groupId>
    <artifactId>functionaljava</artifactId>
    <version>2.8</version>
</dependency>

UPDATE: This just gets more interesting: Lazy Error Handling in Java, Part 2: Thrower is a Monad and Lazy Error Handling in Java, Part 3: Throwing Away Throws.

Thursday, July 10, 2008

Guice, main and startup configuration flags

Here is a small trick we use in an in-house program wired with Google Guice. The goal is to pick the wiring configuration from the command-line without too many contortions.

The idea is to use enums to represent the wiring, and using the command-line to pick the enum. Thus:

enum WhichOne {
   /** Uses module "A", defined elsewhere. */
   ONE(new ModuleA()),
   /** Uses module "A" and "B", defined elsewhere. */
   TWO(new ModuleA(), new ModuleB());

   private final Module module;

   WhichOne(final Module... modules) {
       module = new CompoundModule(modules);
   }

   public Module getModule() {
       return module;
   }
}

class CompoundModule extends AbstractModule {
   private final Module[] modules;

   CompoundModule(final Module... modules) {
       this.modules = modules;
   }

   @Override
   public void configure() {
       for (final Module module : modules)
           install(module);
   }
}

class Main {
    public static void main(final String... arguments) {
        // Real programs use args4j
        final WhichOne whichOne = WhichOne.valueOf(arguments[0]);
        final Module module = whichOne.getModule();
        final Injector injector = Guice.createInjector(module);

        injector.createInstance(MyProgram.class);
   }
}

Now I can pick configuration on the command line:

$ my_program ONE # use module "A"
$ my_program TWO # use module "A" and "B"

Friday, June 20, 2008

Guice support in IntelliJ IDEA

I just had a surprise reply from Dmitriy Demerov of JetBrains:

The latest Early Access Preview builds of Diana (available at http://www.jetbrains.net/confluence/display/IDEADEV/Diana+EAP ) include a plugin for Guice support. You're very much welcome to give it a try and submit your feedback on it.

I had responded to a sales manager at JetBrains that one item on my wish list for IDEA was direct Guice support.

Yippee!

Thursday, May 08, 2008

Bad concurrency advice: interned Strings

I just read Thread Signaling from Jacob Jenkov. It is fine as far as it goes to introduce the reader to Object.wait() and Object.notify().

But it has one fatal flaw: it uses a literal java.lang.String for coordinating between threads. Why is this wrong?

Strings are interned by the compiler. To quote the javadocs: All literal strings and string-valued constant expressions are interned. Using a literal string means that any other code anywhere in the JVM, even in other libraries, which use the same String literal value all share the same object for wait() and notify(). This code:

public void dastardly() {
    "".notify();  
}

will wake up a thread waiting on empty string, including one in utterly unrelated code.

Don't do that. Instead, create a fresh Object for coordinating threads. This age-worn advice for lock objects (synchronize(lock)) applies just as much to objects used to coordinate threads.

Wednesday, May 07, 2008

Friday, May 02, 2008

Good News - JavaOne 2008

JPMorgan is sending me to JavaOne 2008!

Sorry for no posts since November — work has been inordinately busy. I will post from San Francisco.