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();
    }
}