001package org.javasimon.callback.async; 002 003import java.util.concurrent.Callable; 004import java.util.concurrent.ExecutorService; 005import java.util.concurrent.ThreadFactory; 006 007/** 008 * This class contains some basic {@link Executor}s. 009 * <ul> 010 * <li>Disabled: does nothing, callable is not called at all.</li> 011 * <li>Sync: callable is called synchronously, using the same thread as caller, result is returned.</li> 012 * <li>Async: callable is called asynchronously, using the different thread as caller, no result is returned.</li> 013 * </ul> 014 * 015 * @author gerald 016 */ 017public final class Executors { 018 019 /** Disabled Executor. */ 020 public static Executor DISABLED = new Executor() { 021 public Object execute(Callable callable) throws Throwable { 022 return null; 023 } 024 }; 025 /** Synchronous, same thread Executor. */ 026 public static Executor SYNC = new Executor() { 027 public Object execute(Callable callable) throws Throwable { 028 return callable.call(); 029 } 030 }; 031 /** Single threaded executor service used by default async. */ 032 private static ExecutorService ASYNC_EXECUTOR_SERVICE; 033 034 /** Initializes default single threaded executor service. */ 035 private static synchronized ExecutorService initAsyncExecutorService() { 036 if (ASYNC_EXECUTOR_SERVICE == null) { 037 ASYNC_EXECUTOR_SERVICE = java.util.concurrent.Executors.newSingleThreadExecutor( 038 new ThreadFactory() { 039 public Thread newThread(Runnable r) { 040 Thread thread = new Thread(r, "javasimon-async"); 041 thread.setDaemon(true); 042 return thread; 043 } 044 }); 045 } 046 return ASYNC_EXECUTOR_SERVICE; 047 } 048 049 /** Asynchronous, different thread executor. */ 050 private static class AsyncCallbackExecutor<T> implements Executor<T> { 051 /** Used executor service. */ 052 private final ExecutorService executorService; 053 054 public AsyncCallbackExecutor(ExecutorService executorService) { 055 this.executorService = executorService; 056 } 057 058 public T execute(Callable<T> callable) throws Throwable { 059 executorService.submit(callable); 060 return null; 061 } 062 063 } 064 065 /** Returns disabled executor. */ 066 public static <T> Executor<T> disabled() { 067 return DISABLED; 068 } 069 070 /** Returns synchronous, same thread executor. */ 071 public static <T> Executor<T> sync() { 072 return SYNC; 073 } 074 075 /** Returns asynchronous, different thread executor. */ 076 public static <T> Executor<T> async(ExecutorService executorService) { 077 return new AsyncCallbackExecutor(executorService); 078 } 079 080 /** Returns asynchronous, different but unique thread executor. */ 081 public static <T> Executor<T> async() { 082 return async(initAsyncExecutorService()); 083 } 084 085 /** Stops thread used by default async executor. */ 086 public static synchronized void shutdownAsync() { 087 if (ASYNC_EXECUTOR_SERVICE != null) { 088 ASYNC_EXECUTOR_SERVICE.shutdown(); 089 } 090 } 091}