├── .gitignore ├── src ├── main │ ├── resources │ │ └── names.zip │ └── java │ │ └── bbejeck │ │ ├── guava │ │ ├── cache │ │ │ └── service │ │ │ │ ├── SearchService.java │ │ │ │ └── PersonSearchServiceImpl.java │ │ ├── eventbus │ │ │ ├── events │ │ │ │ ├── NoSubscriberEvent.java │ │ │ │ ├── SimpleEvent.java │ │ │ │ ├── PurchaseEvent.java │ │ │ │ ├── CashPurchaseEvent.java │ │ │ │ └── CreditPurchaseEvent.java │ │ │ ├── subscriber │ │ │ │ ├── AllEventSubscriber.java │ │ │ │ ├── PurchaseEventSubscriber.java │ │ │ │ ├── CashPurchaseEventSubscriber.java │ │ │ │ ├── CreditPurchaseEventSubscriber.java │ │ │ │ ├── InvalidSubscriberNoParameters.java │ │ │ │ ├── InvalidSubscriberMultipleParameter.java │ │ │ │ ├── EventSubscriber.java │ │ │ │ ├── LongProcessSubscriber.java │ │ │ │ └── MultiHandlerSubscriber.java │ │ │ └── EventPublisher.java │ │ ├── service │ │ │ ├── SimpleService.java │ │ │ ├── ErrorService.java │ │ │ ├── PrintingServiceListener.java │ │ │ └── ServiceManagerDriver.java │ │ ├── monitor │ │ │ ├── ReentrantLockSample.java │ │ │ ├── MonitorSample.java │ │ │ └── MonitorExample.java │ │ └── striped │ │ │ ├── ConcurrentWorker.java │ │ │ └── StripedExampleDriver.java │ │ └── support │ │ ├── model │ │ └── Person.java │ │ ├── BaseSample.java │ │ ├── lucene │ │ ├── SampleLuceneSearcher.java │ │ └── SampleLuceneIndexBuilder.java │ │ └── database │ │ └── SampleDBService.java └── test │ └── java │ └── bbejeck │ └── guava │ ├── futures │ ├── SearchingTestBase.java │ ├── ListenableFuturesTest.java │ └── FuturesTest.java │ ├── hash │ └── BloomFilterTest.java │ ├── cache │ └── CacheTest.java │ ├── monitor │ └── MonitorExampleTest.java │ └── eventbus │ └── EventBusTest.java ├── README.txt └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .idea/* 3 | *.iml 4 | .idea/libraries 5 | -------------------------------------------------------------------------------- /src/main/resources/names.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbejeck/guava-blog/HEAD/src/main/resources/names.zip -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/cache/service/SearchService.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.cache.service; 2 | 3 | /** 4 | * Created by IntelliJ IDEA. 5 | * User: bbejeck 6 | * Date: 12/10/11 7 | * Time: 9:30 PM 8 | */ 9 | public interface SearchService { 10 | 11 | T search(String query) throws Exception; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | This is the source code for all examples in the Google Guava blog series, uses maven 3.0 2 | 3 | Code for Monitor examples can be found in bbejeck.guava.monitor in the test directory 4 | 5 | Code for Futures and ListenableFutures can be found in bbejeck.guava.futures in the test directory 6 | 7 | The package bbejeck.support cantains all the infrastructure code to facilitate the examples 8 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/eventbus/events/NoSubscriberEvent.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.eventbus.events; 2 | 3 | /** 4 | * Created by IntelliJ IDEA. 5 | * User: bbejeck 6 | * Date: 1/5/12 7 | * Time: 10:22 PM 8 | */ 9 | public class NoSubscriberEvent { 10 | 11 | String message = "I'm lost"; 12 | 13 | public String getMessage() { 14 | return message; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/eventbus/events/SimpleEvent.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.eventbus.events; 2 | 3 | /** 4 | * Created by IntelliJ IDEA. 5 | * User: bbejeck 6 | * Date: 1/3/12 7 | * Time: 10:46 PM 8 | */ 9 | 10 | public class SimpleEvent { 11 | 12 | private String name; 13 | 14 | public SimpleEvent(String name) { 15 | this.name = name; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/eventbus/subscriber/AllEventSubscriber.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.eventbus.subscriber; 2 | 3 | import com.google.common.eventbus.Subscribe; 4 | 5 | /** 6 | * Created by IntelliJ IDEA. 7 | * User: bbejeck 8 | * Date: 1/4/12 9 | * Time: 11:04 PM 10 | */ 11 | public class AllEventSubscriber extends EventSubscriber { 12 | 13 | private AllEventSubscriber() { 14 | } 15 | 16 | @Subscribe 17 | public void handleEvent(Object event) { 18 | events.add(event); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/eventbus/subscriber/PurchaseEventSubscriber.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.eventbus.subscriber; 2 | 3 | import bbejeck.guava.eventbus.events.PurchaseEvent; 4 | import com.google.common.eventbus.Subscribe; 5 | 6 | /** 7 | * Created by IntelliJ IDEA. 8 | * User: bbejeck 9 | * Date: 12/31/11 10 | * Time: 10:39 PM 11 | */ 12 | 13 | public class PurchaseEventSubscriber extends EventSubscriber { 14 | 15 | 16 | private PurchaseEventSubscriber() { 17 | } 18 | 19 | @Subscribe 20 | public void handleEvent(PurchaseEvent event) { 21 | events.add(event); 22 | } 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/eventbus/events/PurchaseEvent.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.eventbus.events; 2 | 3 | /** 4 | * Created by IntelliJ IDEA. 5 | * User: bbejeck 6 | * Date: 12/31/11 7 | * Time: 12:42 PM 8 | */ 9 | 10 | public abstract class PurchaseEvent { 11 | protected long amount; 12 | 13 | public PurchaseEvent(long amount) { 14 | this.amount = amount; 15 | } 16 | 17 | public long getAmount() { 18 | return amount; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return "PurchaseEvent{" + 24 | "amount=" + amount + 25 | '}'; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/eventbus/subscriber/CashPurchaseEventSubscriber.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.eventbus.subscriber; 2 | 3 | import bbejeck.guava.eventbus.events.CashPurchaseEvent; 4 | import com.google.common.eventbus.Subscribe; 5 | 6 | /** 7 | * Created by IntelliJ IDEA. 8 | * User: bbejeck 9 | * Date: 12/31/11 10 | * Time: 10:35 PM 11 | */ 12 | 13 | public class CashPurchaseEventSubscriber extends EventSubscriber { 14 | 15 | 16 | private CashPurchaseEventSubscriber() { 17 | } 18 | 19 | @Subscribe 20 | public void handleEvent(CashPurchaseEvent event) { 21 | events.add(event); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/eventbus/subscriber/CreditPurchaseEventSubscriber.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.eventbus.subscriber; 2 | 3 | import bbejeck.guava.eventbus.events.CreditPurchaseEvent; 4 | import com.google.common.eventbus.Subscribe; 5 | 6 | /** 7 | * Created by IntelliJ IDEA. 8 | * User: bbejeck 9 | * Date: 12/31/11 10 | * Time: 10:37 PM 11 | */ 12 | 13 | public class CreditPurchaseEventSubscriber extends EventSubscriber { 14 | 15 | private CreditPurchaseEventSubscriber() { 16 | } 17 | 18 | @Subscribe 19 | public void handleEvent(CreditPurchaseEvent event) { 20 | events.add(event); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/support/model/Person.java: -------------------------------------------------------------------------------- 1 | package bbejeck.support.model; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * Created by IntelliJ IDEA. 7 | * User: bbejeck 8 | * Date: 11/23/11 9 | * Time: 8:38 PM 10 | */ 11 | 12 | public class Person { 13 | 14 | public final String firstName; 15 | public final String lastName; 16 | public final String address; 17 | public final String email; 18 | 19 | 20 | public Person(Map values){ 21 | firstName = values.get("first_name"); 22 | lastName = values.get("last_name"); 23 | address = values.get("address"); 24 | email = values.get("email"); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/support/BaseSample.java: -------------------------------------------------------------------------------- 1 | package bbejeck.support; 2 | 3 | import com.google.common.util.concurrent.ListeningExecutorService; 4 | import com.google.common.util.concurrent.MoreExecutors; 5 | 6 | import java.util.concurrent.Executors; 7 | 8 | /** 9 | * Created by IntelliJ IDEA. 10 | * User: bbejeck 11 | * Date: 11/23/11 12 | * Time: 2:31 PM 13 | */ 14 | public class BaseSample { 15 | 16 | protected ListeningExecutorService executorService; 17 | 18 | public BaseSample(){ 19 | executorService = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()); 20 | } 21 | 22 | public void shutDown(){ 23 | executorService.shutdownNow(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/eventbus/events/CashPurchaseEvent.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.eventbus.events; 2 | 3 | /** 4 | * Created by IntelliJ IDEA. 5 | * User: bbejeck 6 | * Date: 12/29/11 7 | * Time: 11:12 PM 8 | */ 9 | 10 | public class CashPurchaseEvent extends PurchaseEvent { 11 | 12 | private String item; 13 | 14 | public CashPurchaseEvent(long amount, String item) { 15 | super(amount); 16 | this.item = item; 17 | } 18 | 19 | public String getItem() { 20 | return item; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return "CashPurchaseEvent{" + 26 | "item='" + item + '\'' + 27 | "} " + super.toString(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/service/SimpleService.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.service; 2 | 3 | 4 | import com.google.common.util.concurrent.AbstractExecutionThreadService; 5 | 6 | /** 7 | * User: Bill Bejeck 8 | * Date: 2/19/14 9 | * Time: 10:58 PM 10 | */ 11 | public class SimpleService extends AbstractExecutionThreadService { 12 | 13 | 14 | @Override 15 | protected void run() throws Exception { 16 | int count = 0; 17 | while (count++ < 1) { 18 | System.out.println("Simple Service Running...."); 19 | Thread.sleep(300l); 20 | System.out.println("Doing some tasks ..."); 21 | } 22 | Thread.sleep(100l); 23 | System.out.println("All done now"); 24 | } 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/service/ErrorService.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.service; 2 | 3 | import com.google.common.util.concurrent.AbstractService; 4 | 5 | /** 6 | * User: Bill Bejeck 7 | * Date: 2/20/14 8 | * Time: 11:25 PM 9 | */ 10 | public class ErrorService extends AbstractService { 11 | private boolean throwError = true; 12 | 13 | @Override 14 | protected void doStart() { 15 | super.notifyStarted(); 16 | System.out.println("Error service is running now"); 17 | if (throwError) { 18 | throwError = false; 19 | throw new RuntimeException("Error"); 20 | } 21 | } 22 | 23 | @Override 24 | protected void doStop() { 25 | super.notifyStopped(); 26 | System.out.println("Error service is stopping now"); 27 | } 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/eventbus/subscriber/InvalidSubscriberNoParameters.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.eventbus.subscriber; 2 | 3 | import com.google.common.eventbus.EventBus; 4 | import com.google.common.eventbus.Subscribe; 5 | 6 | /** 7 | * Created by IntelliJ IDEA. 8 | * User: bbejeck 9 | * Date: 1/6/12 10 | * Time: 12:21 AM 11 | */ 12 | public class InvalidSubscriberNoParameters { 13 | 14 | private InvalidSubscriberNoParameters() { 15 | } 16 | 17 | @Subscribe 18 | public void handleEvent() { 19 | //DO nothing will not work 20 | } 21 | 22 | public static InvalidSubscriberNoParameters instance(EventBus eventBus) { 23 | InvalidSubscriberNoParameters subscriber = new InvalidSubscriberNoParameters(); 24 | eventBus.register(subscriber); 25 | return subscriber; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/eventbus/subscriber/InvalidSubscriberMultipleParameter.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.eventbus.subscriber; 2 | 3 | import bbejeck.guava.eventbus.events.CreditPurchaseEvent; 4 | import com.google.common.eventbus.EventBus; 5 | import com.google.common.eventbus.Subscribe; 6 | 7 | /** 8 | * Created by IntelliJ IDEA. 9 | * User: bbejeck 10 | * Date: 1/6/12 11 | * Time: 12:14 AM 12 | */ 13 | public class InvalidSubscriberMultipleParameter { 14 | 15 | 16 | private InvalidSubscriberMultipleParameter() { 17 | } 18 | 19 | @Subscribe 20 | public void handleCreditEvent(CreditPurchaseEvent event, Object foo) { 21 | //DO nothing this will not work 22 | } 23 | 24 | public static InvalidSubscriberMultipleParameter instance(EventBus eventBus) { 25 | InvalidSubscriberMultipleParameter subscriber = new InvalidSubscriberMultipleParameter(); 26 | eventBus.register(subscriber); 27 | return subscriber; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/monitor/ReentrantLockSample.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.monitor; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.concurrent.locks.Condition; 6 | import java.util.concurrent.locks.ReentrantLock; 7 | 8 | /** 9 | * Created by IntelliJ IDEA. 10 | * User: bbejeck 11 | * Date: 11/14/11 12 | * Time: 9:40 PM 13 | */ 14 | public class ReentrantLockSample { 15 | private List list = new ArrayList(); 16 | private static final int MAX_SIZE = 10; 17 | 18 | private ReentrantLock rLock = new ReentrantLock(); 19 | private Condition listAtCapacity = rLock.newCondition(); 20 | 21 | public void addToList(String item) throws InterruptedException { 22 | rLock.lock(); 23 | try { 24 | while (list.size() == MAX_SIZE) { 25 | listAtCapacity.await(); 26 | } 27 | list.add(item); 28 | } finally { 29 | rLock.unlock(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/monitor/MonitorSample.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.monitor; 2 | 3 | import com.google.common.util.concurrent.Monitor; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * Created by IntelliJ IDEA. 10 | * User: bbejeck 11 | * Date: 11/14/11 12 | * Time: 10:01 PM 13 | */ 14 | public class MonitorSample { 15 | private List list = new ArrayList(); 16 | private static final int MAX_SIZE = 10; 17 | 18 | private Monitor monitor = new Monitor(); 19 | private Monitor.Guard listBelowCapacity = new Monitor.Guard(monitor) { 20 | @Override 21 | public boolean isSatisfied() { 22 | return (list.size() < MAX_SIZE); 23 | } 24 | }; 25 | 26 | public void addToList(String item) throws InterruptedException { 27 | monitor.enterWhen(listBelowCapacity); 28 | try { 29 | list.add(item); 30 | } finally { 31 | monitor.leave(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/eventbus/events/CreditPurchaseEvent.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.eventbus.events; 2 | 3 | /** 4 | * Created by IntelliJ IDEA. 5 | * User: bbejeck 6 | * Date: 12/31/11 7 | * Time: 12:50 PM 8 | */ 9 | 10 | public class CreditPurchaseEvent extends PurchaseEvent { 11 | 12 | private String creditCardNumber; 13 | private String item; 14 | 15 | public CreditPurchaseEvent(long amount, String item, String creditCardNumber) { 16 | super(amount); 17 | this.item = item; 18 | this.creditCardNumber = creditCardNumber; 19 | } 20 | 21 | public String getCreditCardNumber() { 22 | return creditCardNumber; 23 | } 24 | 25 | public String getItem() { 26 | return item; 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "CreditPurchaseEvent{" + 32 | "creditCardNumber='" + creditCardNumber + '\'' + 33 | ", item='" + item + '\'' + 34 | "} " + super.toString(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/service/PrintingServiceListener.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.service; 2 | 3 | import com.google.common.util.concurrent.Service; 4 | 5 | /** 6 | * User: Bill Bejeck 7 | * Date: 2/20/14 8 | * Time: 10:59 PM 9 | */ 10 | public class PrintingServiceListener extends Service.Listener { 11 | 12 | 13 | @Override 14 | public void starting() { 15 | print("Service.Listener: Starting"); 16 | } 17 | 18 | @Override 19 | public void running() { 20 | print("Service.Listener: Running"); 21 | } 22 | 23 | @Override 24 | public void stopping(Service.State from) { 25 | print("Service.Listener: stopping from state " + from); 26 | } 27 | 28 | @Override 29 | public void terminated(Service.State from) { 30 | print("Service.Listener: terminated from state " + from); 31 | } 32 | 33 | @Override 34 | public void failed(Service.State from, Throwable failure) { 35 | print("Service.Listener: error from state " + from + " with error " + failure); 36 | } 37 | 38 | private void print(String message) { 39 | System.out.println(message); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/striped/ConcurrentWorker.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.striped; 2 | 3 | import com.google.common.util.concurrent.Striped; 4 | 5 | import java.util.concurrent.Semaphore; 6 | 7 | /** 8 | * User: Bill Bejeck 9 | * Date: 9/17/13 10 | * Time: 8:47 PM 11 | *

12 | * This is a simple class to demonstrate using 13 | * the Guava Striped class 14 | */ 15 | public class ConcurrentWorker { 16 | 17 | private Striped stripedSemaphores = Striped.semaphore(10, 3); 18 | private Semaphore semaphore = new Semaphore(3); 19 | 20 | public void stripedConcurrentAccess(String url) throws Exception { 21 | Semaphore stripedSemaphore = stripedSemaphores.get(url); 22 | stripedSemaphore.acquire(); 23 | try { 24 | //Access restricted resource here 25 | Thread.sleep(25); 26 | } finally { 27 | stripedSemaphore.release(); 28 | } 29 | } 30 | 31 | public void nonStripedConcurrentAccess(String url) throws Exception { 32 | semaphore.acquire(); 33 | try { 34 | //Access restricted resource here 35 | Thread.sleep(25); 36 | } finally { 37 | semaphore.release(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/eventbus/EventPublisher.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.eventbus; 2 | 3 | import bbejeck.guava.eventbus.events.CashPurchaseEvent; 4 | import bbejeck.guava.eventbus.events.CreditPurchaseEvent; 5 | import bbejeck.guava.eventbus.events.NoSubscriberEvent; 6 | import bbejeck.guava.eventbus.events.SimpleEvent; 7 | import com.google.common.eventbus.EventBus; 8 | 9 | /** 10 | * Created by IntelliJ IDEA. 11 | * User: bbejeck 12 | * Date: 12/29/11 13 | * Time: 11:15 PM 14 | */ 15 | 16 | public class EventPublisher { 17 | 18 | EventBus eventBus; 19 | 20 | public EventPublisher(EventBus eventBus) { 21 | this.eventBus = eventBus; 22 | } 23 | 24 | public void createCashPurchaseEvent(String description, long amount) { 25 | eventBus.post(new CashPurchaseEvent(amount, description)); 26 | } 27 | 28 | public void createCreditPurchaseEvent(String item, String ccNumber, long amount) { 29 | eventBus.post(new CreditPurchaseEvent(amount, ccNumber, item)); 30 | } 31 | 32 | public void createSimpleEvent(String eventName) { 33 | eventBus.post(new SimpleEvent(eventName)); 34 | } 35 | 36 | public void createNoSubscribedEvent() { 37 | eventBus.post(new NoSubscriberEvent()); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/eventbus/subscriber/EventSubscriber.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.eventbus.subscriber; 2 | 3 | import com.google.common.eventbus.EventBus; 4 | 5 | import java.lang.reflect.Constructor; 6 | import java.lang.reflect.InvocationTargetException; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * Created by IntelliJ IDEA. 12 | * User: bbejeck 13 | * Date: 12/31/11 14 | * Time: 10:04 PM 15 | */ 16 | 17 | public abstract class EventSubscriber { 18 | 19 | List events = new ArrayList(); 20 | 21 | public List getHandledEvents() { 22 | return events; 23 | } 24 | 25 | 26 | public static E factory(Class clazz, EventBus eventBus) { 27 | E subscriber = null; 28 | try { 29 | Constructor constructor = clazz.getDeclaredConstructors()[0]; 30 | constructor.setAccessible(true); 31 | subscriber = (E) constructor.newInstance(new Object[]{}); 32 | eventBus.register(subscriber); 33 | } catch (InstantiationException e) { 34 | e.printStackTrace(); 35 | } catch (IllegalAccessException e) { 36 | e.printStackTrace(); 37 | } catch (InvocationTargetException e) { 38 | e.printStackTrace(); 39 | } 40 | 41 | return subscriber; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/eventbus/subscriber/LongProcessSubscriber.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.eventbus.subscriber; 2 | 3 | import bbejeck.guava.eventbus.events.CashPurchaseEvent; 4 | import bbejeck.guava.eventbus.events.CreditPurchaseEvent; 5 | import com.google.common.eventbus.AllowConcurrentEvents; 6 | import com.google.common.eventbus.AsyncEventBus; 7 | import com.google.common.eventbus.Subscribe; 8 | 9 | import java.util.concurrent.CountDownLatch; 10 | 11 | /** 12 | * Created by IntelliJ IDEA. 13 | * User: bbejeck 14 | * Date: 1/1/12 15 | * Time: 1:56 PM 16 | */ 17 | public class LongProcessSubscriber { 18 | 19 | private CountDownLatch doneSignal; 20 | 21 | private LongProcessSubscriber(CountDownLatch doneSignal) { 22 | this.doneSignal = doneSignal; 23 | } 24 | 25 | @Subscribe 26 | @AllowConcurrentEvents 27 | public void handleEventConcurrent(CreditPurchaseEvent event) { 28 | pause(300l); 29 | doneSignal.countDown(); 30 | } 31 | 32 | @Subscribe 33 | public void handleEventNonConcurrent(CashPurchaseEvent event) { 34 | pause(300l); 35 | doneSignal.countDown(); 36 | } 37 | 38 | private void pause(long time) { 39 | try { 40 | Thread.sleep(time); 41 | } catch (InterruptedException e) { 42 | //Ignore 43 | } 44 | } 45 | 46 | public static LongProcessSubscriber instance(AsyncEventBus asyncEventBus, CountDownLatch countDownLatch) { 47 | LongProcessSubscriber subscriber = new LongProcessSubscriber(countDownLatch); 48 | asyncEventBus.register(subscriber); 49 | return subscriber; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/eventbus/subscriber/MultiHandlerSubscriber.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.eventbus.subscriber; 2 | 3 | import bbejeck.guava.eventbus.events.CashPurchaseEvent; 4 | import bbejeck.guava.eventbus.events.CreditPurchaseEvent; 5 | import bbejeck.guava.eventbus.events.SimpleEvent; 6 | import com.google.common.eventbus.EventBus; 7 | import com.google.common.eventbus.Subscribe; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | /** 13 | * Created by IntelliJ IDEA. 14 | * User: bbejeck 15 | * Date: 1/5/12 16 | * Time: 10:36 PM 17 | */ 18 | public class MultiHandlerSubscriber { 19 | 20 | private List cashEvents = new ArrayList(); 21 | private List creditEvents = new ArrayList(); 22 | private List simpleEvents = new ArrayList(); 23 | 24 | private MultiHandlerSubscriber() { 25 | } 26 | 27 | @Subscribe 28 | public void handleCashEvents(CashPurchaseEvent event) { 29 | cashEvents.add(event); 30 | } 31 | 32 | @Subscribe 33 | public void handleCreditEvents(CreditPurchaseEvent event) { 34 | creditEvents.add(event); 35 | } 36 | 37 | @Subscribe 38 | public void handleSimpleEvents(SimpleEvent event) { 39 | simpleEvents.add(event); 40 | } 41 | 42 | public List getCashEvents() { 43 | return cashEvents; 44 | } 45 | 46 | public List getCreditEvents() { 47 | return creditEvents; 48 | } 49 | 50 | public List getSimpleEvents() { 51 | return simpleEvents; 52 | } 53 | 54 | public static MultiHandlerSubscriber instance(EventBus eventBus) { 55 | MultiHandlerSubscriber subscriber = new MultiHandlerSubscriber(); 56 | eventBus.register(subscriber); 57 | return subscriber; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/cache/service/PersonSearchServiceImpl.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.cache.service; 2 | 3 | import bbejeck.support.database.SampleDBService; 4 | import bbejeck.support.lucene.SampleLuceneSearcher; 5 | import bbejeck.support.model.Person; 6 | import com.google.common.cache.Cache; 7 | import com.google.common.cache.CacheBuilder; 8 | import com.google.common.cache.CacheLoader; 9 | import com.google.common.cache.LoadingCache; 10 | 11 | import java.util.List; 12 | import java.util.concurrent.TimeUnit; 13 | 14 | /** 15 | * Created by IntelliJ IDEA. 16 | * User: bbejeck 17 | * Date: 12/10/11 18 | * Time: 9:33 PM 19 | */ 20 | public class PersonSearchServiceImpl implements SearchService> { 21 | 22 | protected LoadingCache> cache; 23 | private SampleLuceneSearcher luceneSearcher; 24 | private SampleDBService dbService; 25 | 26 | public PersonSearchServiceImpl(SampleLuceneSearcher luceneSearcher, SampleDBService dbService) { 27 | this.luceneSearcher = luceneSearcher; 28 | this.dbService = dbService; 29 | buildCache(); 30 | } 31 | 32 | @Override 33 | public List search(String query) throws Exception { 34 | return cache.get(query); 35 | } 36 | 37 | private void buildCache() { 38 | cache = CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES) 39 | .maximumSize(1000) 40 | .build(new CacheLoader>() { 41 | @Override 42 | public List load(String queryKey) throws Exception { 43 | List ids = luceneSearcher.search(queryKey); 44 | return dbService.getPersonsById(ids); 45 | } 46 | }); 47 | } 48 | 49 | public Cache> getCache() { 50 | return cache; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/service/ServiceManagerDriver.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.service; 2 | 3 | import com.google.common.collect.Lists; 4 | import com.google.common.util.concurrent.MoreExecutors; 5 | import com.google.common.util.concurrent.Service; 6 | import com.google.common.util.concurrent.ServiceManager; 7 | 8 | import java.util.Date; 9 | import java.util.List; 10 | 11 | /** 12 | * User: Bill Bejeck 13 | * Date: 2/19/14 14 | * Time: 11:15 PM 15 | */ 16 | public class ServiceManagerDriver { 17 | 18 | public static void main(String[] args) { 19 | 20 | List services = Lists.newArrayList(); 21 | SimpleService service = new SimpleService(); 22 | ErrorService errorService = new ErrorService(); 23 | service.addListener(new PrintingServiceListener(), MoreExecutors.sameThreadExecutor()); 24 | errorService.addListener(new PrintingServiceListener(), MoreExecutors.sameThreadExecutor()); 25 | services.add(service); 26 | services.add(errorService); 27 | ServiceManager serviceManager = new ServiceManager(services); 28 | serviceManager.addListener(new ServiceManager.Listener() { 29 | @Override 30 | public void healthy() { 31 | System.out.println("ServiceManager.Listener:Service is healthy"); 32 | } 33 | 34 | @Override 35 | public void stopped() { 36 | System.out.println("ServiceManager.Listener:Service has stopped"); 37 | } 38 | 39 | @Override 40 | public void failure(Service service) { 41 | System.out.println("ServiceManager.Listener:" + service.failureCause().getMessage()); 42 | System.out.println(service.toString()); 43 | } 44 | }); 45 | serviceManager.startAsync(); 46 | System.out.println("Service started " + new Date() + " waiting to stop"); 47 | serviceManager.awaitStopped(); 48 | System.out.println("Service stopped " + new Date() + " all done"); 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | bbejeck.guava 5 | guava-blog 6 | jar 7 | 1.0 8 | guava-blog 9 | http://maven.apache.org 10 | 11 | 12 | com.google.guava 13 | guava 14 | 16.0.1 15 | 16 | 17 | org.apache.commons 18 | commons-lang3 19 | 3.1 20 | 21 | 22 | org.apache.lucene 23 | lucene-core 24 | 3.5.0 25 | 26 | 27 | com.h2database 28 | h2 29 | 1.3.165 30 | 31 | 32 | com.google.inject 33 | guice 34 | 3.0 35 | 36 | 37 | junit 38 | junit 39 | 4.10 40 | test 41 | 42 | 43 | 44 | 45 | 46 | org.apache.maven.plugins 47 | maven-compiler-plugin 48 | 2.0.2 49 | 50 | 1.6 51 | 1.6 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/support/lucene/SampleLuceneSearcher.java: -------------------------------------------------------------------------------- 1 | package bbejeck.support.lucene; 2 | 3 | import bbejeck.support.BaseSample; 4 | import com.google.common.util.concurrent.ListenableFuture; 5 | import org.apache.lucene.analysis.standard.StandardAnalyzer; 6 | import org.apache.lucene.document.Document; 7 | import org.apache.lucene.index.IndexReader; 8 | import org.apache.lucene.queryParser.QueryParser; 9 | import org.apache.lucene.search.IndexSearcher; 10 | import org.apache.lucene.search.Query; 11 | import org.apache.lucene.search.ScoreDoc; 12 | import org.apache.lucene.search.TopDocs; 13 | import org.apache.lucene.store.RAMDirectory; 14 | import org.apache.lucene.util.Version; 15 | 16 | import java.io.IOException; 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | import java.util.concurrent.Callable; 20 | 21 | /** 22 | * Created by IntelliJ IDEA. 23 | * User: bbejeck 24 | * Date: 11/20/11 25 | * Time: 2:06 PM 26 | */ 27 | public class SampleLuceneSearcher extends BaseSample { 28 | 29 | private IndexSearcher searcher; 30 | private final int MAX_RESULTS = 1000; 31 | 32 | public SampleLuceneSearcher(RAMDirectory ramDirectory) { 33 | try { 34 | searcher = new IndexSearcher(IndexReader.open(ramDirectory, true)); 35 | } catch (IOException e) { 36 | throw new RuntimeException(e); 37 | } 38 | } 39 | 40 | public List search(String query) throws Exception { 41 | List results = new ArrayList(); 42 | QueryParser queryParser = new QueryParser(Version.LUCENE_35, null, new StandardAnalyzer(Version.LUCENE_35)); 43 | Query q = queryParser.parse(query); 44 | TopDocs topDocs = searcher.search(q, MAX_RESULTS); 45 | for (ScoreDoc sd : topDocs.scoreDocs) { 46 | Document document = searcher.doc(sd.doc); 47 | results.add(document.get("id")); 48 | } 49 | return results; 50 | } 51 | 52 | public ListenableFuture> searchAsync(final String query) { 53 | return executorService.submit(new Callable>() { 54 | @Override 55 | public List call() throws Exception { 56 | return search(query); 57 | } 58 | }); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/support/lucene/SampleLuceneIndexBuilder.java: -------------------------------------------------------------------------------- 1 | package bbejeck.support.lucene; 2 | 3 | import org.apache.lucene.analysis.standard.StandardAnalyzer; 4 | import org.apache.lucene.document.Document; 5 | import org.apache.lucene.document.Field; 6 | import org.apache.lucene.index.IndexWriter; 7 | import org.apache.lucene.index.IndexWriterConfig; 8 | import org.apache.lucene.store.RAMDirectory; 9 | import org.apache.lucene.util.Version; 10 | 11 | import java.io.BufferedReader; 12 | import java.io.FileReader; 13 | import java.io.IOException; 14 | 15 | public class SampleLuceneIndexBuilder { 16 | 17 | private String namesFile; 18 | 19 | public SampleLuceneIndexBuilder(String namesFile) { 20 | this.namesFile = namesFile; 21 | } 22 | 23 | public RAMDirectory buildIndex() throws IOException { 24 | RAMDirectory ramDirectory = new RAMDirectory(); 25 | Document doc = new Document(); 26 | Field[] fields = new Field[]{new Field("firstName", "", Field.Store.NO, Field.Index.ANALYZED_NO_NORMS), 27 | new Field("lastName", "", Field.Store.NO, Field.Index.ANALYZED_NO_NORMS), 28 | new Field("address", "", Field.Store.NO, Field.Index.ANALYZED_NO_NORMS), 29 | new Field("email", "", Field.Store.NO, Field.Index.ANALYZED_NO_NORMS), 30 | new Field("id", "", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)}; 31 | addFieldsToDocument(doc, fields); 32 | 33 | BufferedReader reader = new BufferedReader(new FileReader(namesFile)); 34 | 35 | IndexWriter indexWriter = new IndexWriter(ramDirectory, new IndexWriterConfig(Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35))); 36 | 37 | String line; 38 | while ((line = reader.readLine()) != null) { 39 | String[] personData = getPersonData(line); 40 | setFieldData(personData, fields); 41 | indexWriter.addDocument(doc); 42 | } 43 | indexWriter.close(); 44 | return ramDirectory; 45 | } 46 | 47 | private String[] getPersonData(String line) { 48 | return line.split(","); 49 | } 50 | 51 | private void setFieldData(String[] data, Field[] fields) { 52 | int index = 0; 53 | for (Field field : fields) { 54 | field.setValue(data[index++]); 55 | } 56 | } 57 | 58 | private void addFieldsToDocument(Document doc, Field[] fields) { 59 | for (Field field : fields) { 60 | doc.add(field); 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/monitor/MonitorExample.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.monitor; 2 | 3 | import com.google.common.util.concurrent.Monitor; 4 | 5 | import java.util.concurrent.atomic.AtomicInteger; 6 | 7 | /** 8 | * Created by IntelliJ IDEA. 9 | * User: bbejeck 10 | * Date: 11/11/11 11 | * Time: 10:01 PM 12 | */ 13 | public class MonitorExample { 14 | 15 | private final Monitor monitor = new Monitor(); 16 | private volatile boolean condition = true; 17 | private int taskDoneCounter; 18 | private AtomicInteger taskSkippedCounter = new AtomicInteger(0); 19 | private int stopTaskCount; 20 | 21 | private Monitor.Guard conditionGuard = new Monitor.Guard(monitor) { 22 | @Override 23 | public boolean isSatisfied() { 24 | return condition; 25 | } 26 | }; 27 | 28 | public void demoTryEnterIf() throws InterruptedException { 29 | if (monitor.tryEnterIf(conditionGuard)) { 30 | try { 31 | simulatedWork(); 32 | taskDoneCounter++; 33 | } finally { 34 | monitor.leave(); 35 | } 36 | } else { 37 | taskSkippedCounter.incrementAndGet(); 38 | } 39 | } 40 | 41 | public void demoEnterIf() throws InterruptedException { 42 | if (monitor.enterIf(conditionGuard)) { 43 | try { 44 | taskDoneCounter++; 45 | if (taskDoneCounter == stopTaskCount) { 46 | condition = false; 47 | } 48 | } finally { 49 | monitor.leave(); 50 | } 51 | } else { 52 | taskSkippedCounter.incrementAndGet(); 53 | } 54 | 55 | } 56 | 57 | public void demoEnterWhen() throws InterruptedException { 58 | monitor.enterWhen(conditionGuard); 59 | try { 60 | taskDoneCounter++; 61 | if (taskDoneCounter == stopTaskCount) { 62 | condition = false; 63 | } 64 | } finally { 65 | monitor.leave(); 66 | } 67 | } 68 | 69 | private void simulatedWork() throws InterruptedException { 70 | Thread.sleep(250); 71 | } 72 | 73 | public int getStopTaskCount() { 74 | return stopTaskCount; 75 | } 76 | 77 | public void setStopTaskCount(int stopTaskCount) { 78 | this.stopTaskCount = stopTaskCount; 79 | } 80 | 81 | public void setCondition(boolean condition) { 82 | this.condition = condition; 83 | } 84 | 85 | public int getTaskSkippedCounter() { 86 | return taskSkippedCounter.get(); 87 | } 88 | 89 | public int getTaskDoneCounter() { 90 | return taskDoneCounter; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/guava/futures/SearchingTestBase.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.futures; 2 | 3 | import bbejeck.support.database.SampleDBService; 4 | import bbejeck.support.lucene.SampleLuceneIndexBuilder; 5 | import bbejeck.support.lucene.SampleLuceneSearcher; 6 | import org.apache.lucene.store.RAMDirectory; 7 | import org.h2.jdbcx.JdbcConnectionPool; 8 | import org.h2.tools.Server; 9 | import org.junit.AfterClass; 10 | import org.junit.BeforeClass; 11 | 12 | import java.io.IOException; 13 | import java.sql.Connection; 14 | import java.sql.SQLException; 15 | import java.sql.Statement; 16 | 17 | /** 18 | * Created by IntelliJ IDEA. 19 | * User: bbejeck 20 | * Date: 11/23/11 21 | * Time: 3:04 PM 22 | */ 23 | 24 | public abstract class SearchingTestBase { 25 | 26 | 27 | private static final String dbUrl = "jdbc:h2:mem:test"; 28 | private static final String insertSql = " CREATE TABLE PERSON(FIRST_NAME VARCHAR(255), LAST_NAME VARCHAR(255)," + 29 | " ADDRESS VARCHAR(255), EMAIL VARCHAR(255),ID INT PRIMARY KEY) AS SELECT * FROM CSVREAD('classpath:names.csv')"; 30 | protected static JdbcConnectionPool connectionPool; 31 | private static Server dbServer; 32 | private static SampleLuceneIndexBuilder luceneIndexBuilder; 33 | protected static SampleLuceneSearcher luceneSearcher; 34 | protected static SampleDBService dbService; 35 | 36 | @BeforeClass 37 | public static void setUpBeforeAllTests() throws Exception { 38 | startH2(); 39 | setUpIndex(); 40 | createConnectionPool(); 41 | populateDb(); 42 | dbService = new SampleDBService(connectionPool); 43 | } 44 | 45 | @AfterClass 46 | public static void shutDownAfterAllTests() throws Exception { 47 | stopH2(); 48 | closeConnectionPool(); 49 | luceneSearcher.shutDown(); 50 | dbService.shutDown(); 51 | } 52 | 53 | private static void populateDb() throws SQLException { 54 | Connection connection = connectionPool.getConnection(); 55 | Statement statement = connection.createStatement(); 56 | statement.execute(insertSql); 57 | statement.close(); 58 | connection.close(); 59 | } 60 | 61 | private static void setUpIndex() throws IOException { 62 | String filePath = System.getProperty("names","src/main/resources/names.csv"); 63 | luceneIndexBuilder = new SampleLuceneIndexBuilder(filePath); 64 | RAMDirectory ramDirectory = luceneIndexBuilder.buildIndex(); 65 | luceneSearcher = new SampleLuceneSearcher(ramDirectory); 66 | } 67 | 68 | private static void startH2() throws Exception { 69 | dbServer = Server.createTcpServer(); 70 | dbServer.start(); 71 | } 72 | 73 | private static void stopH2() throws Exception { 74 | dbServer.stop(); 75 | } 76 | 77 | private static void createConnectionPool() throws Exception { 78 | Class.forName("org.h2.Driver"); 79 | connectionPool = JdbcConnectionPool.create(dbUrl, "sa", "sa"); 80 | } 81 | 82 | private static void closeConnectionPool() throws Exception { 83 | connectionPool.dispose(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/guava/hash/BloomFilterTest.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.hash; 2 | 3 | import com.google.common.hash.BloomFilter; 4 | import com.google.common.hash.Funnel; 5 | import com.google.common.hash.PrimitiveSink; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | import java.math.BigInteger; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | import java.util.Random; 13 | 14 | import static org.hamcrest.CoreMatchers.is; 15 | import static org.junit.Assert.assertThat; 16 | 17 | /** 18 | * Created by IntelliJ IDEA. 19 | * User: bbejeck 20 | */ 21 | 22 | public class BloomFilterTest { 23 | 24 | private BloomFilter bloomFilter; 25 | private Random random; 26 | private int numBits; 27 | private List stored; 28 | private List notStored; 29 | 30 | @Before 31 | public void setUp() { 32 | numBits = 128; 33 | random = new Random(); 34 | stored = new ArrayList(); 35 | notStored = new ArrayList(); 36 | loadBigIntList(stored, 1000); 37 | loadBigIntList(notStored, 100); 38 | } 39 | 40 | @Test 41 | public void testMayContain() { 42 | setUpBloomFilter(stored.size()); 43 | int falsePositiveCount = 0; 44 | for (BigInteger bigInteger : notStored) { 45 | boolean mightContain = bloomFilter.mightContain(bigInteger); 46 | boolean isStored = stored.contains(bigInteger); 47 | if (mightContain && !isStored) { 48 | falsePositiveCount++; 49 | } 50 | } 51 | assertThat(falsePositiveCount < 5, is(true)); 52 | } 53 | 54 | @Test 55 | public void testMayContainGoOverInsertions() { 56 | setUpBloomFilter(50); 57 | int falsePositiveCount = 0; 58 | for (BigInteger bigInteger : notStored) { 59 | boolean mightContain = bloomFilter.mightContain(bigInteger); 60 | boolean isStored = stored.contains(bigInteger); 61 | if (mightContain && !isStored) { 62 | falsePositiveCount++; 63 | } 64 | } 65 | assertThat(falsePositiveCount, is(notStored.size())); 66 | } 67 | 68 | private void setUpBloomFilter(int numInsertions) { 69 | bloomFilter = BloomFilter.create(new BigIntegerFunnel(), numInsertions); 70 | addStoredBigIntegersToBloomFilter(); 71 | } 72 | 73 | private BigInteger getRandomBigInteger() { 74 | return new BigInteger(numBits, random); 75 | } 76 | 77 | private void addStoredBigIntegersToBloomFilter() { 78 | for (BigInteger bigInteger : stored) { 79 | bloomFilter.put(bigInteger); 80 | } 81 | } 82 | 83 | private void loadBigIntList(List list, int count) { 84 | for (int i = 0; i < count; i++) { 85 | list.add(getRandomBigInteger()); 86 | } 87 | } 88 | 89 | private class BigIntegerFunnel implements Funnel { 90 | @Override 91 | public void funnel(BigInteger from, PrimitiveSink into) { 92 | into.putBytes(from.toByteArray()); 93 | } 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/guava/striped/StripedExampleDriver.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.striped; 2 | 3 | import com.google.common.base.Stopwatch; 4 | import com.google.common.collect.Lists; 5 | 6 | import java.util.List; 7 | import java.util.concurrent.*; 8 | 9 | /** 10 | * User: Bill Bejeck 11 | * Date: 9/19/13 12 | * Time: 9:50 PM 13 | */ 14 | public class StripedExampleDriver { 15 | 16 | private ExecutorService executorService = Executors.newCachedThreadPool(); 17 | private int numberThreads = 300; 18 | private CountDownLatch startSignal = new CountDownLatch(1); 19 | private CountDownLatch endSignal = new CountDownLatch(numberThreads); 20 | private Stopwatch stopwatch = Stopwatch.createUnstarted(); 21 | private ConcurrentWorker worker = new ConcurrentWorker(); 22 | private static final boolean USE_STRIPES = true; 23 | private static final boolean NO_STRIPES = false; 24 | private static final int POSSIBLE_TASKS_PER_THREAD = 10; 25 | private List data = Lists.newArrayList(); 26 | 27 | 28 | public static void main(String[] args) throws Exception { 29 | StripedExampleDriver driver = new StripedExampleDriver(); 30 | driver.createData(); 31 | driver.runStripedExample(); 32 | driver.reset(); 33 | driver.runNonStripedExample(); 34 | driver.shutdown(); 35 | } 36 | 37 | private void runStripedExample() throws InterruptedException { 38 | runExample(worker, USE_STRIPES, "Striped work"); 39 | } 40 | 41 | private void runNonStripedExample() throws InterruptedException { 42 | runExample(worker, NO_STRIPES, "Non-Striped work"); 43 | } 44 | 45 | 46 | private void runExample(final ConcurrentWorker worker, final boolean isStriped, String type) throws InterruptedException { 47 | for (int i = 0; i < numberThreads; i++) { 48 | final String value = getValue(i % POSSIBLE_TASKS_PER_THREAD); 49 | executorService.submit(new Callable() { 50 | @Override 51 | public Void call() throws Exception { 52 | startSignal.await(); 53 | if (isStriped) { 54 | worker.stripedConcurrentAccess(value); 55 | } else { 56 | worker.nonStripedConcurrentAccess(value); 57 | } 58 | endSignal.countDown(); 59 | return null; 60 | } 61 | }); 62 | } 63 | stopwatch.start(); 64 | startSignal.countDown(); 65 | endSignal.await(); 66 | stopwatch.stop(); 67 | System.out.println("Time for" + type + " work [" + stopwatch.elapsed(TimeUnit.MILLISECONDS) + "] millis"); 68 | } 69 | 70 | private void createData() { 71 | for (int i = 0; i < POSSIBLE_TASKS_PER_THREAD; i++) { 72 | data.add("Task_" + i); 73 | } 74 | } 75 | 76 | private String getValue(int index) { 77 | return data.get(index); 78 | } 79 | 80 | 81 | private void reset() { 82 | startSignal = new CountDownLatch(1); 83 | endSignal = new CountDownLatch(numberThreads); 84 | stopwatch.reset(); 85 | } 86 | 87 | private void shutdown() { 88 | executorService.shutdownNow(); 89 | } 90 | 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/guava/futures/ListenableFuturesTest.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.futures; 2 | 3 | import com.google.common.util.concurrent.*; 4 | import org.junit.After; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | import java.util.concurrent.Callable; 9 | import java.util.concurrent.CountDownLatch; 10 | import java.util.concurrent.Executors; 11 | import java.util.concurrent.TimeUnit; 12 | 13 | import static org.hamcrest.CoreMatchers.is; 14 | import static org.junit.Assert.assertThat; 15 | 16 | /** 17 | * Created by IntelliJ IDEA. 18 | * User: bbejeck 19 | * Date: 11/21/11 20 | * Time: 10:50 PM 21 | */ 22 | 23 | 24 | public class ListenableFuturesTest { 25 | 26 | private ListeningExecutorService executorService; 27 | private CountDownLatch startSignal; 28 | private CountDownLatch endSignal; 29 | private static final int NUM_THREADS = 5; 30 | private boolean callbackRan; 31 | 32 | 33 | @Before 34 | public void setUp() { 35 | executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(NUM_THREADS)); 36 | startSignal = new CountDownLatch(1); 37 | endSignal = new CountDownLatch(1); 38 | callbackRan = false; 39 | 40 | } 41 | 42 | @After 43 | public void tearDown() { 44 | executorService.shutdownNow(); 45 | } 46 | 47 | @Test 48 | public void testRunListenableFutureWithCallback() throws Exception { 49 | ListenableFuture futureTask = executorService.submit(new Task()); 50 | futureTask.addListener(new Runnable() { 51 | @Override 52 | public void run() { 53 | callbackRan = true; 54 | endSignal.countDown(); 55 | } 56 | }, executorService); 57 | 58 | endSignal.await(); 59 | assertThat(callbackRan, is(true)); 60 | } 61 | 62 | @Test 63 | public void testRunListenableFutureWithFutureCallbackSuccess() throws Exception { 64 | ListenableFuture futureTask = executorService.submit(new Task(startSignal)); 65 | FutureCallbackImpl callback = new FutureCallbackImpl(); 66 | Futures.addCallback(futureTask, callback); 67 | startSignal.countDown(); 68 | endSignal.await(); 69 | assertThat(callback.getCallbackResult(), is("Task Done successfully")); 70 | } 71 | 72 | @Test 73 | public void testRunListenableFutureWithFutureCallbackFailure() throws Exception { 74 | ListenableFuture futureTask = executorService.submit(new Task(null)); 75 | FutureCallbackImpl callback = new FutureCallbackImpl(); 76 | Futures.addCallback(futureTask, callback); 77 | //startSignal.countDown(); don't call countdown 78 | endSignal.await(); 79 | assertThat(callback.getCallbackResult(), is("java.lang.NullPointerException")); 80 | } 81 | 82 | 83 | private class FutureCallbackImpl implements FutureCallback { 84 | 85 | private StringBuilder builder = new StringBuilder(); 86 | 87 | @Override 88 | public void onSuccess(String result) { 89 | builder.append(result).append(" successfully"); 90 | done(); 91 | 92 | } 93 | 94 | @Override 95 | public void onFailure(Throwable t) { 96 | builder.append(t.toString()); 97 | done(); 98 | } 99 | 100 | private void done() { 101 | endSignal.countDown(); 102 | } 103 | 104 | public String getCallbackResult() { 105 | return builder.toString(); 106 | } 107 | } 108 | 109 | 110 | private class Task implements Callable { 111 | private CountDownLatch start; 112 | 113 | public Task() { 114 | } 115 | 116 | public Task(CountDownLatch start) { 117 | this.start = start; 118 | } 119 | 120 | @Override 121 | public String call() throws Exception { 122 | this.start.await(1, TimeUnit.SECONDS); 123 | Thread.sleep(1000); 124 | return "Task Done"; 125 | } 126 | } 127 | 128 | 129 | } 130 | -------------------------------------------------------------------------------- /src/main/java/bbejeck/support/database/SampleDBService.java: -------------------------------------------------------------------------------- 1 | package bbejeck.support.database; 2 | 3 | import bbejeck.support.BaseSample; 4 | import bbejeck.support.model.Person; 5 | import com.google.common.util.concurrent.ListenableFuture; 6 | import org.h2.jdbcx.JdbcConnectionPool; 7 | 8 | import java.sql.Connection; 9 | import java.sql.ResultSet; 10 | import java.sql.SQLException; 11 | import java.sql.Statement; 12 | import java.util.ArrayList; 13 | import java.util.HashMap; 14 | import java.util.List; 15 | import java.util.Map; 16 | import java.util.concurrent.Callable; 17 | 18 | /** 19 | * Created by IntelliJ IDEA. 20 | * User: bbejeck 21 | * Date: 11/20/11 22 | * Time: 10:51 PM 23 | */ 24 | 25 | public class SampleDBService extends BaseSample { 26 | 27 | private JdbcConnectionPool connectionPool; 28 | private String query = "Select first_name,last_name,address,email from person where id in("; 29 | private static final String FIRST_NAME = "first_name"; 30 | private static final String LAST_NAME = "last_name"; 31 | private static final String ADDRESS = "address"; 32 | private static final String EMAIL = "email"; 33 | 34 | public SampleDBService(JdbcConnectionPool connectionPool) { 35 | this.connectionPool = connectionPool; 36 | } 37 | 38 | public List> getPersonDataById(List rawIds) { 39 | try { 40 | StringBuilder queryBuilder = new StringBuilder(query); 41 | queryBuilder.append(buildInList(rawIds)).append(')'); 42 | Connection connection = connectionPool.getConnection(); 43 | Statement statement = connection.createStatement(); 44 | ResultSet resultSet = executeQuery(statement, queryBuilder.toString()); 45 | List> results = extractResults(resultSet); 46 | close(resultSet, statement, connection); 47 | 48 | return results; 49 | } catch (SQLException e) { 50 | throw new RuntimeException(e); 51 | } 52 | } 53 | 54 | private void close(ResultSet resultSet, Statement statement, Connection connection) throws SQLException { 55 | resultSet.close(); 56 | statement.close(); 57 | connection.close(); 58 | } 59 | 60 | public ListenableFuture>> getPersonDataByIdAsync(final List ids) { 61 | return executorService.submit(new Callable>>() { 62 | @Override 63 | public List> call() throws Exception { 64 | return getPersonDataById(ids); 65 | } 66 | }); 67 | } 68 | 69 | public ListenableFuture> getPersonsByIdAsync(final List ids) { 70 | return executorService.submit(new Callable>() { 71 | @Override 72 | public List call() throws Exception { 73 | return getPersonsById(ids); 74 | } 75 | }); 76 | } 77 | 78 | public List getPersonsById(List ids) { 79 | List> personData = getPersonDataById(ids); 80 | List people = new ArrayList(); 81 | for (Map data : personData) { 82 | people.add(new Person(data)); 83 | } 84 | return people; 85 | } 86 | 87 | private List> extractResults(ResultSet resultSet) { 88 | List> allResults = new ArrayList>(); 89 | try { 90 | while (resultSet.next()) { 91 | Map rowResults = new HashMap(); 92 | rowResults.put(FIRST_NAME, resultSet.getString(FIRST_NAME)); 93 | rowResults.put(LAST_NAME, resultSet.getString(LAST_NAME)); 94 | rowResults.put(ADDRESS, resultSet.getString(ADDRESS)); 95 | rowResults.put(EMAIL, resultSet.getString(EMAIL)); 96 | allResults.add(rowResults); 97 | } 98 | } catch (SQLException e) { 99 | throw new RuntimeException(e); 100 | } 101 | return allResults; 102 | } 103 | 104 | private ResultSet executeQuery(Statement statement, String query) throws SQLException { 105 | return statement.executeQuery(query); 106 | } 107 | 108 | private String buildInList(List rawIds) { 109 | StringBuilder builder = new StringBuilder(); 110 | for (String rawId : rawIds) { 111 | builder.append(rawId).append(','); 112 | } 113 | builder.setLength(builder.length() - 1); 114 | return builder.toString(); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/guava/cache/CacheTest.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.cache; 2 | 3 | import bbejeck.guava.futures.SearchingTestBase; 4 | import bbejeck.support.model.Person; 5 | import com.google.common.base.Function; 6 | import com.google.common.cache.*; 7 | import org.junit.Test; 8 | 9 | import java.util.List; 10 | import java.util.concurrent.TimeUnit; 11 | 12 | import static org.hamcrest.CoreMatchers.is; 13 | import static org.junit.Assert.assertThat; 14 | 15 | /** 16 | * Created by IntelliJ IDEA. 17 | * User: bbejeck 18 | * Date: 12/13/11 19 | * Time: 9:12 PM 20 | */ 21 | 22 | public class CacheTest extends SearchingTestBase { 23 | 24 | 25 | @Test 26 | public void testCacheWithFastRemovalsAfterWrite() throws Exception { 27 | 28 | PersonListRemovalListener removalListener = new PersonListRemovalListener(); 29 | 30 | LoadingCache> cache = CacheBuilder.newBuilder().expireAfterWrite(500, TimeUnit.MILLISECONDS) 31 | .removalListener(removalListener) 32 | .recordStats() 33 | .build(getCacheLoader()); 34 | 35 | String queryKey = "firstName:bob"; 36 | List personList = cache.get(queryKey); 37 | List personListII = cache.get(queryKey); 38 | Thread.sleep(500); 39 | List personListIII = cache.get(queryKey); 40 | assertThat(personList == personListII, is(true)); 41 | assertThat(personList == personListIII, is(false)); 42 | 43 | RemovalNotification> removalNotification = removalListener.getRemovalNotification(); 44 | assertThat(removalNotification.getValue() == personList, is(true)); 45 | assertThat(removalNotification.getCause(), is(RemovalCause.EXPIRED)); 46 | 47 | CacheStats stats = cache.stats(); 48 | assertThat(stats.hitCount(), is(1l)); 49 | assertThat(stats.loadCount(), is(2l)); 50 | assertThat(stats.missCount(), is(2l)); 51 | } 52 | 53 | @Test 54 | public void testCacheLoadedAfterFirstRequestThenCached() throws Exception { 55 | LoadingCache> cache = CacheBuilder.newBuilder().recordStats().build(CacheLoader.from(getFunction())); 56 | String queryKey = "lastName:smith"; 57 | List personList = null; 58 | for (int i = 0; i < 100; i++) { 59 | personList = cache.get(queryKey); 60 | } 61 | CacheStats stats = cache.stats(); 62 | assertThat(stats.hitCount(), is(99l)); 63 | assertThat(stats.loadCount(), is(1l)); 64 | assertThat(stats.missCount(), is(1l)); 65 | assertThat(stats.requestCount(), is(100l)); 66 | assertThat(personList.size(), is(620)); 67 | for (Person person : personList) { 68 | assertThat(person.lastName, is("Smith")); 69 | } 70 | } 71 | 72 | @Test 73 | public void testCacheSizeLimit() throws Exception { 74 | PersonListRemovalListener removalListener = new PersonListRemovalListener(); 75 | LoadingCache> cache = CacheBuilder.newBuilder() 76 | .maximumSize(2) 77 | .removalListener(removalListener) 78 | .build(CacheLoader.from(getFunction())); 79 | String queryKey = "lastName:smith"; 80 | String queryKeyII = "firstName:bob"; 81 | String queryKeyIII = "firstName:joe"; 82 | 83 | cache.get(queryKey); 84 | cache.get(queryKeyII); 85 | cache.get(queryKeyIII); 86 | assertThat(removalListener.getRemovalNotification().getKey(), is(queryKey)); 87 | assertThat(removalListener.getRemovalNotification().getCause(),is(RemovalCause.SIZE)); 88 | } 89 | 90 | 91 | private class PersonListRemovalListener implements RemovalListener> { 92 | 93 | private RemovalNotification> removalNotification; 94 | 95 | @Override 96 | public void onRemoval(RemovalNotification> removalNotification) { 97 | this.removalNotification = removalNotification; 98 | } 99 | 100 | public RemovalNotification> getRemovalNotification() { 101 | return removalNotification; 102 | } 103 | } 104 | 105 | private CacheLoader> getCacheLoader() { 106 | return new CacheLoader>() { 107 | @Override 108 | public List load(String key) throws Exception { 109 | List ids = luceneSearcher.search(key); 110 | return dbService.getPersonsById(ids); 111 | } 112 | }; 113 | } 114 | 115 | private Function> getFunction() { 116 | return new Function>() { 117 | @Override 118 | public List apply(String searchKey) { 119 | try { 120 | List ids = luceneSearcher.search(searchKey); 121 | return dbService.getPersonsById(ids); 122 | } catch (Exception e) { 123 | throw new RuntimeException(e); 124 | } 125 | } 126 | }; 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/guava/monitor/MonitorExampleTest.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.monitor; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.lang.reflect.Method; 8 | import java.util.concurrent.*; 9 | 10 | import static org.hamcrest.CoreMatchers.is; 11 | import static org.junit.Assert.assertThat; 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * User: bbejeck 16 | * Date: 11/11/11 17 | * Time: 11:48 PM 18 | */ 19 | public class MonitorExampleTest { 20 | 21 | private MonitorExample monitorExample; 22 | private ExecutorService executorService; 23 | private int numberThreads = 10; 24 | private CountDownLatch startSignal; 25 | private CountDownLatch doneSignal; 26 | 27 | @Before 28 | public void setUp() throws Exception { 29 | monitorExample = new MonitorExample(); 30 | executorService = Executors.newFixedThreadPool(numberThreads); 31 | startSignal = new CountDownLatch(1); 32 | doneSignal = new CountDownLatch(numberThreads); 33 | } 34 | 35 | @After 36 | public void tearDown() { 37 | executorService.shutdownNow(); 38 | } 39 | 40 | /* 41 | * First thread does some simulated work and the following 42 | * 9 threads will move on. 43 | */ 44 | @Test 45 | public void testDemoTryEnterIf() throws Exception { 46 | setUpThreadsForTestingMethod("demoTryEnterIf"); 47 | startAllThreadsForTest(); 48 | waitForTestThreadsToFinish(); 49 | int expectedTaskCount = 1; 50 | int expectedSkippedTasks = 9; 51 | assertThat(monitorExample.getTaskDoneCounter(), is(expectedTaskCount)); 52 | assertThat(monitorExample.getTaskSkippedCounter(), is(expectedSkippedTasks)); 53 | } 54 | 55 | /* 56 | The first 5 threads will wait for the monitor because 57 | the guard condition is true, but once it turns false the 58 | rest of the threads drop off 59 | */ 60 | @Test 61 | public void testDemoEnterIfOnlyFiveTasksComplete() throws Exception { 62 | monitorExample.setStopTaskCount(5); 63 | setUpThreadsForTestingMethod("demoEnterIf"); 64 | 65 | startAllThreadsForTest(); 66 | waitForTestThreadsToFinish(); 67 | int expectedTaskCount = 5; 68 | int expectedSkippedTasks = 5; 69 | 70 | assertThat(monitorExample.getTaskDoneCounter(), is(expectedTaskCount)); 71 | assertThat(monitorExample.getTaskSkippedCounter(), is(expectedSkippedTasks)); 72 | 73 | } 74 | 75 | /* 76 | All 10 threads enter the monitor as the guard condition 77 | remains true the entire time. 78 | */ 79 | @Test 80 | public void testDemoEnterIfAllTasksComplete() throws Exception { 81 | monitorExample.setStopTaskCount(Integer.MAX_VALUE); 82 | setUpThreadsForTestingMethod("demoEnterIf"); 83 | 84 | startAllThreadsForTest(); 85 | waitForTestThreadsToFinish(); 86 | int expectedTaskCount = 10; 87 | int expectedSkippedTasks = 0; 88 | 89 | assertThat(monitorExample.getTaskDoneCounter(), is(expectedTaskCount)); 90 | assertThat(monitorExample.getTaskSkippedCounter(), is(expectedSkippedTasks)); 91 | 92 | } 93 | 94 | /* 95 | Guard condition is initially false, but all 10 threads 96 | enter the monitor. 97 | */ 98 | @Test 99 | public void testDemoEnterWhen() throws Exception { 100 | monitorExample.setStopTaskCount(Integer.MAX_VALUE); 101 | monitorExample.setCondition(false); 102 | setUpThreadsForTestingMethod("demoEnterWhen"); 103 | startAllThreadsForTest(); 104 | int expectedCompletedCount = 0; 105 | int completedCount = monitorExample.getTaskDoneCounter(); 106 | assertThat(completedCount, is(expectedCompletedCount)); 107 | 108 | monitorExample.setCondition(true); 109 | 110 | waitForTestThreadsToFinish(); 111 | expectedCompletedCount = 10; 112 | completedCount = monitorExample.getTaskDoneCounter(); 113 | assertThat(completedCount, is(expectedCompletedCount)); 114 | } 115 | 116 | /* 117 | Artificially setting the guard to false after 3 threads complete to demonstrate that 118 | the remaining 7 threads will wait until the guard condition returns true again and will 119 | enter the monitor. 120 | */ 121 | @Test 122 | public void testDemoEnterWhenAllTasksCompleteEvenWhenConditionChanges() throws Exception { 123 | monitorExample.setCondition(true); 124 | monitorExample.setStopTaskCount(3); 125 | setUpThreadsForTestingMethod("demoEnterWhen"); 126 | startAllThreadsForTest(); 127 | 128 | //verifying that only 3 threads have initially worked, re-set the guard to true 129 | FutureTask checkInitialTasksCompleted = new FutureTask( 130 | new Callable() { 131 | public Integer call() { 132 | int initialCompletedTasks = monitorExample.getTaskDoneCounter(); 133 | monitorExample.setCondition(true); 134 | return initialCompletedTasks; 135 | 136 | } 137 | }); 138 | 139 | new Thread(checkInitialTasksCompleted).start(); 140 | 141 | int expectedCompletedCount = 3; 142 | int completedCount = checkInitialTasksCompleted.get(); 143 | assertThat(completedCount, is(expectedCompletedCount)); 144 | 145 | waitForTestThreadsToFinish(); 146 | assertThat(completedCount, is(expectedCompletedCount)); 147 | expectedCompletedCount = 10; 148 | completedCount = monitorExample.getTaskDoneCounter(); 149 | assertThat(completedCount, is(expectedCompletedCount)); 150 | } 151 | 152 | private void waitForTestThreadsToFinish() throws InterruptedException { 153 | doneSignal.await(1000l, TimeUnit.MILLISECONDS); 154 | } 155 | 156 | private void startAllThreadsForTest() { 157 | startSignal.countDown(); 158 | } 159 | 160 | private Method getMethodUnderTest(String methodName) throws Exception { 161 | return monitorExample.getClass().getDeclaredMethod(methodName); 162 | } 163 | 164 | 165 | private void setUpThreadsForTestingMethod(String methodName) throws Exception { 166 | final Method testMethod = getMethodUnderTest(methodName); 167 | for (int i = 0; i < numberThreads; i++) { 168 | executorService.execute(new Runnable() { 169 | @Override 170 | public void run() { 171 | try { 172 | startSignal.await(); 173 | testMethod.invoke(monitorExample); 174 | } catch (Exception e) { 175 | //Don't care 176 | } finally { 177 | doneSignal.countDown(); 178 | } 179 | } 180 | }); 181 | } 182 | } 183 | 184 | } 185 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/guava/futures/FuturesTest.java: -------------------------------------------------------------------------------- 1 | //package bbejeck.guava.futures; 2 | // 3 | //import bbejeck.support.model.Person; 4 | //import com.google.common.base.Function; 5 | //import com.google.common.util.concurrent.*; 6 | //import org.junit.After; 7 | //import org.junit.Before; 8 | //import org.junit.Test; 9 | // 10 | //import java.util.List; 11 | //import java.util.concurrent.*; 12 | // 13 | //import static org.hamcrest.CoreMatchers.is; 14 | //import static org.hamcrest.CoreMatchers.nullValue; 15 | //import static org.junit.Assert.assertThat; 16 | //import static org.junit.Assert.fail; 17 | // 18 | ///** 19 | // * Created by IntelliJ IDEA. 20 | // * User: bbejeck 21 | // * Date: 11/20/11 22 | // * Time: 2:11 PM 23 | // */ 24 | // 25 | //public class FuturesTest extends SearchingTestBase { 26 | // 27 | // private int numberTasks; 28 | // private CountDownLatch startSignal; 29 | // private CountDownLatch doneSignal; 30 | // private ListeningExecutorService executorService; 31 | // 32 | // @Before 33 | // public void setUp() throws Exception { 34 | // numberTasks = 5; 35 | // startSignal = new CountDownLatch(1); 36 | // doneSignal = new CountDownLatch(numberTasks); 37 | // executorService = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()); 38 | // } 39 | // 40 | // @After 41 | // public void tearDown() { 42 | // executorService.shutdownNow(); 43 | // } 44 | // 45 | // 46 | // 47 | // @Test 48 | // public void testChainSearchSettableFuture() throws Exception { 49 | // 50 | // Function, ListenableFuture>> queryFunction = new Function, ListenableFuture>>() { 51 | // @Override 52 | // public ListenableFuture> apply(final List ids) { 53 | // SettableFuture> sf = SettableFuture.create(); 54 | // sf.set(dbService.getPersonsById(ids)); 55 | // return sf; 56 | // } 57 | // }; 58 | // 59 | // ListenableFuture> indexSearch = luceneSearcher.searchAsync("firstName:martin"); 60 | // 61 | // ListenableFuture> results = Futures.transform(indexSearch, queryFunction); 62 | // List persons = results.get(1, TimeUnit.SECONDS); 63 | // assertThat(persons.size(), is(74)); 64 | // for(Person person : persons){ 65 | // assertThat(person.firstName,is("Martin")); 66 | // } 67 | // } 68 | // 69 | // @Test 70 | // public void testChainSearchFunction() throws Exception { 71 | // 72 | // 73 | // AsyncFunction, List> queryFunction = new AsyncFunction, List>() { 74 | // @Override 75 | // public ListenableFuture> apply(final List ids) { 76 | // return dbService.getPersonsByIdAsync(ids); 77 | // } 78 | // }; 79 | // 80 | // ListenableFuture> indexSearch = luceneSearcher.searchAsync("firstName:martin"); 81 | // 82 | // ListenableFuture> results = Futures.transform(indexSearch, queryFunction,executorService); 83 | // List persons = results.get(1, TimeUnit.SECONDS); 84 | // assertThat(persons.size(), is(74)); 85 | // for(Person person : persons){ 86 | // assertThat(person.firstName,is("Martin")); 87 | // } 88 | // } 89 | // 90 | // 91 | // @Test 92 | // public void testTransformSearch() throws Exception { 93 | // 94 | // Function, List> transformSearchResults = new Function, List>() { 95 | // @Override 96 | // public List apply(List ids) { 97 | // return dbService.getPersonsById(ids); 98 | // } 99 | // }; 100 | // 101 | // ListenableFuture> indexSearch = luceneSearcher.searchAsync("firstName:martin"); 102 | // ListenableFuture> transformedResults = Futures.transform(indexSearch, transformSearchResults,executorService); 103 | // 104 | // List persons = transformedResults.get(1, TimeUnit.SECONDS); 105 | // int expectedSize = 74; 106 | // assertThat(persons.size(), is(expectedSize)); 107 | // for (Person person : persons) { 108 | // assertThat(person.firstName, is("Martin")); 109 | // } 110 | // } 111 | // 112 | // @Test 113 | // public void allAsListSuccess() throws Exception { 114 | // ListenableFuture> lf1 = getPersonsByFirstNameFuture("martin", false); 115 | // ListenableFuture> lf2 = getPersonsByFirstNameFuture("bob", false); 116 | // ListenableFuture> lf3 = getPersonsByFirstNameFuture("emily", false); 117 | // ListenableFuture> lf4 = getPersonsByFirstNameFuture("mona", false); 118 | // ListenableFuture> lf5 = getPersonsByFirstNameFuture("tom", false); 119 | // 120 | // ListenableFuture>> lfResults = Futures.allAsList(lf1, lf2, lf3, lf4, lf5); 121 | // startSignal.countDown(); 122 | // List> listOfPersonLists = lfResults.get(); 123 | // assertThat(listOfPersonLists.size()>0,is(true)); 124 | // for(List personList : listOfPersonLists){ 125 | // assertThat(personList.size() > 0,is(true)); 126 | // } 127 | // } 128 | // 129 | // @Test(expected = ExecutionException.class) 130 | // public void allAsListSuccessOneFailure() throws Exception { 131 | // ListenableFuture> lf1 = getPersonsByFirstNameFuture("martin", false); 132 | // ListenableFuture> lf2 = getPersonsByFirstNameFuture("bob", false); 133 | // ListenableFuture> lf3 = getPersonsByFirstNameFuture("emily", true); 134 | // ListenableFuture> lf4 = getPersonsByFirstNameFuture("mona", false); 135 | // ListenableFuture> lf5 = getPersonsByFirstNameFuture("tom", false); 136 | // 137 | // ListenableFuture>> lfResults = Futures.allAsList(lf1, lf2, lf3, lf4, lf5); 138 | // startSignal.countDown(); 139 | // List> listOfPersonLists = lfResults.get(); 140 | // fail("should not get here"); 141 | // } 142 | // 143 | // @Test 144 | // public void successfulAsListSuccessOneFailure() throws Exception { 145 | // ListenableFuture> lf1 = getPersonsByFirstNameFuture("martin", true); 146 | // ListenableFuture> lf2 = getPersonsByFirstNameFuture("bob", false); 147 | // ListenableFuture> lf3 = getPersonsByFirstNameFuture("emily", true); 148 | // ListenableFuture> lf4 = getPersonsByFirstNameFuture("mona", false); 149 | // ListenableFuture> lf5 = getPersonsByFirstNameFuture("tom", false); 150 | // 151 | // ListenableFuture>> lfResults = Futures.successfulAsList(lf1, lf2, lf3, lf4, lf5); 152 | // startSignal.countDown(); 153 | // List> listOfPersonLists = lfResults.get(); 154 | // 155 | // assertThat(listOfPersonLists.size()==5,is(true)); 156 | // 157 | // //have null values failed 158 | // assertThat(listOfPersonLists.get(0),is(nullValue())); 159 | // assertThat(listOfPersonLists.get(2),is(nullValue())); 160 | // 161 | // //succeeded returned valid results 162 | // assertThat(listOfPersonLists.get(1).size() > 0,is(true)); 163 | // assertThat(listOfPersonLists.get(3).size() > 0,is(true)); 164 | // assertThat(listOfPersonLists.get(4).size() > 0,is(true)); 165 | // } 166 | // 167 | // private ListenableFuture> getPersonsByFirstNameFuture(final String firstName, final boolean error) { 168 | // return executorService.submit(new Callable>() { 169 | // @Override 170 | // public List call() throws Exception { 171 | // startSignal.await(); 172 | // if (error) { 173 | // throw new RuntimeException("Ooops!"); 174 | // } 175 | // List ids = luceneSearcher.search("firstName:" + firstName); 176 | // List persons = dbService.getPersonsById(ids); 177 | // return persons; 178 | // } 179 | // }); 180 | // } 181 | // 182 | // private Callable getSimpleCallable(final String label) { 183 | // return new Callable() { 184 | // @Override 185 | // public String call() throws Exception { 186 | // return label; 187 | // } 188 | // }; 189 | // } 190 | //} 191 | -------------------------------------------------------------------------------- /src/test/java/bbejeck/guava/eventbus/EventBusTest.java: -------------------------------------------------------------------------------- 1 | package bbejeck.guava.eventbus; 2 | 3 | import bbejeck.guava.eventbus.events.CashPurchaseEvent; 4 | import bbejeck.guava.eventbus.events.CreditPurchaseEvent; 5 | import bbejeck.guava.eventbus.events.NoSubscriberEvent; 6 | import bbejeck.guava.eventbus.subscriber.*; 7 | import com.google.common.eventbus.AsyncEventBus; 8 | import com.google.common.eventbus.DeadEvent; 9 | import com.google.common.eventbus.EventBus; 10 | import com.google.common.eventbus.Subscribe; 11 | import org.junit.Before; 12 | import org.junit.Test; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | import java.util.concurrent.CountDownLatch; 17 | import java.util.concurrent.Executors; 18 | 19 | import static org.hamcrest.CoreMatchers.is; 20 | import static org.junit.Assert.*; 21 | 22 | /** 23 | * Created by IntelliJ IDEA. 24 | * User: bbejeck 25 | * Date: 12/29/11 26 | * Time: 11:34 PM 27 | */ 28 | public class EventBusTest { 29 | 30 | private EventPublisher eventPublisher; 31 | private CashPurchaseEventSubscriber cashPurchaseEventSubscriber; 32 | private CreditPurchaseEventSubscriber creditPurchaseEventSubscriber; 33 | private PurchaseEventSubscriber purchaseEventSubscriber; 34 | private EventBus eventBus; 35 | private AsyncEventBus asyncEventBus; 36 | private LongProcessSubscriber longProcessSubscriber; 37 | private DeadEventSubscriber deadEventSubscriber; 38 | private AllEventSubscriber allEventSubscriber; 39 | private MultiHandlerSubscriber multiHandlerSubscriber; 40 | private CountDownLatch doneSignal; 41 | private int numberLongEvents = 10; 42 | 43 | 44 | @Before 45 | public void setUp() { 46 | eventBus = new EventBus(); 47 | deadEventSubscriber = new DeadEventSubscriber(); 48 | eventBus.register(deadEventSubscriber); 49 | eventPublisher = new EventPublisher(eventBus); 50 | cashPurchaseEventSubscriber = EventSubscriber.factory(CashPurchaseEventSubscriber.class, eventBus); 51 | creditPurchaseEventSubscriber = EventSubscriber.factory(CreditPurchaseEventSubscriber.class, eventBus); 52 | purchaseEventSubscriber = EventSubscriber.factory(PurchaseEventSubscriber.class, eventBus); 53 | multiHandlerSubscriber = MultiHandlerSubscriber.instance(eventBus); 54 | } 55 | 56 | @Test 57 | public void testCashPurchaseEventReceived() { 58 | generateCashPurchaseEvent(); 59 | assertThat(cashPurchaseEventSubscriber.getHandledEvents().size(), is(1)); 60 | assertThat(creditPurchaseEventSubscriber.getHandledEvents().size(), is(0)); 61 | assertSame(cashPurchaseEventSubscriber.getHandledEvents().get(0).getClass(), CashPurchaseEvent.class); 62 | assertThat(deadEventSubscriber.deadEvents.size(), is(0)); 63 | } 64 | 65 | @Test 66 | public void testDeadEvent() { 67 | eventPublisher.createNoSubscribedEvent(); 68 | assertThat(deadEventSubscriber.deadEvents.size(), is(1)); 69 | DeadEvent deadEvent = deadEventSubscriber.deadEvents.get(0); 70 | assertSame(deadEvent.getEvent().getClass(), NoSubscriberEvent.class); 71 | } 72 | 73 | 74 | @Test 75 | public void testCreditCardPurchaseEventReceived() { 76 | generateCreditPurchaseEvent(); 77 | assertThat(cashPurchaseEventSubscriber.getHandledEvents().size(), is(0)); 78 | assertThat(creditPurchaseEventSubscriber.getHandledEvents().size(), is(1)); 79 | assertSame(creditPurchaseEventSubscriber.getHandledEvents().get(0).getClass(), CreditPurchaseEvent.class); 80 | } 81 | 82 | 83 | @Test 84 | public void testGetAllPurchaseEvents() { 85 | generateAllPurchaseEvents(); 86 | assertThat(purchaseEventSubscriber.getHandledEvents().size(), is(2)); 87 | assertSame(purchaseEventSubscriber.getHandledEvents().get(0).getClass(), CashPurchaseEvent.class); 88 | assertSame(purchaseEventSubscriber.getHandledEvents().get(1).getClass(), CreditPurchaseEvent.class); 89 | } 90 | 91 | @Test 92 | public void testUnregisterForEvents() { 93 | eventBus.unregister(cashPurchaseEventSubscriber); 94 | CashPurchaseEventSubscriber cashPurchaseEventSubscriber1 = EventSubscriber.factory(CashPurchaseEventSubscriber.class, eventBus); 95 | CashPurchaseEventSubscriber cashPurchaseEventSubscriber2 = EventSubscriber.factory(CashPurchaseEventSubscriber.class, eventBus); 96 | eventBus.register(cashPurchaseEventSubscriber1); 97 | eventBus.register(cashPurchaseEventSubscriber2); 98 | 99 | generateCashPurchaseEvent(); 100 | assertThat(cashPurchaseEventSubscriber.getHandledEvents().size(), is(0)); 101 | assertThat(cashPurchaseEventSubscriber1.getHandledEvents().size(), is(1)); 102 | assertThat(cashPurchaseEventSubscriber2.getHandledEvents().size(), is(1)); 103 | } 104 | 105 | /** 106 | * Handler for CreditEvent has @AllowConcurrentEvents and each invocation 107 | * of the handler takes 300 MS, but done in parallel s only takes approximately 108 | * 300 MS to run 109 | */ 110 | @Test 111 | public void testAsyncEventSubscriber() throws Exception { 112 | asyncEventBus = new AsyncEventBus(Executors.newCachedThreadPool()); 113 | doneSignal = new CountDownLatch(numberLongEvents); 114 | longProcessSubscriber = LongProcessSubscriber.instance(asyncEventBus, doneSignal); 115 | 116 | long start = System.currentTimeMillis(); 117 | for (int i = 0; i < numberLongEvents; i++) { 118 | asyncEventBus.post(new CreditPurchaseEvent(1000l, "Stuff", "1234678")); 119 | } 120 | doneSignal.await(); 121 | long elapsed = start - System.currentTimeMillis(); 122 | assertTrue(elapsed <= 300l && elapsed < 500l); 123 | } 124 | 125 | /** 126 | * Handler for CashEvent does not @AllowConcurrentEvents and each invocation 127 | * of the handler takes 1 sec, even though using AsyncEventBus it takes a full 128 | * 3 seconds to run, so all calls are serial! 129 | */ 130 | @Test 131 | public void testNonAsyncEventSubscriber() throws Exception { 132 | asyncEventBus = new AsyncEventBus(Executors.newCachedThreadPool()); 133 | doneSignal = new CountDownLatch(numberLongEvents); 134 | longProcessSubscriber = LongProcessSubscriber.instance(asyncEventBus, doneSignal); 135 | 136 | long start = System.currentTimeMillis(); 137 | for (int i = 0; i < numberLongEvents; i++) { 138 | asyncEventBus.post(new CashPurchaseEvent(1000l, "Stuff")); 139 | } 140 | doneSignal.await(); 141 | long elapsed = start - System.currentTimeMillis(); 142 | assertTrue(elapsed <= 3000l && elapsed < 3500l); 143 | } 144 | 145 | @Test 146 | public void testHandleAllEvents() { 147 | allEventSubscriber = EventSubscriber.factory(AllEventSubscriber.class, eventBus); 148 | generateAllPurchaseEvents(); 149 | generateSimpleEvent(); 150 | assertThat(allEventSubscriber.getHandledEvents().size(), is(3)); 151 | } 152 | 153 | @Test 154 | public void testMultiHandlerSubscriber() { 155 | generateCashPurchaseEvent(); 156 | generateCreditPurchaseEvent(); 157 | generateSimpleEvent(); 158 | assertThat(multiHandlerSubscriber.getCashEvents().size(), is(1)); 159 | assertThat(multiHandlerSubscriber.getCreditEvents().size(), is(1)); 160 | assertThat(multiHandlerSubscriber.getSimpleEvents().size(), is(1)); 161 | } 162 | 163 | @Test(expected = IllegalArgumentException.class) 164 | public void testMultipleParametersInHandler() { 165 | InvalidSubscriberMultipleParameter invalidSubscriber = InvalidSubscriberMultipleParameter.instance(eventBus); 166 | generateCreditPurchaseEvent(); 167 | } 168 | 169 | @Test(expected = IllegalArgumentException.class) 170 | public void testNoParametersInHandler() { 171 | InvalidSubscriberNoParameters invalidSubscriber = InvalidSubscriberNoParameters.instance(eventBus); 172 | generateCreditPurchaseEvent(); 173 | } 174 | 175 | 176 | private void generateSimpleEvent() { 177 | eventPublisher.createSimpleEvent("simpleEvent"); 178 | } 179 | 180 | private void generateAllPurchaseEvents() { 181 | generateCashPurchaseEvent(); 182 | generateCreditPurchaseEvent(); 183 | } 184 | 185 | private void generateCreditPurchaseEvent() { 186 | eventPublisher.createCreditPurchaseEvent("Plane Tickets", "123456789", 25900l); 187 | } 188 | 189 | private void generateCashPurchaseEvent() { 190 | eventPublisher.createCashPurchaseEvent("Jeep Wrangler", 25000l); 191 | } 192 | 193 | 194 | private class DeadEventSubscriber { 195 | List deadEvents = new ArrayList(); 196 | 197 | @Subscribe 198 | public void handleDeadEvent(DeadEvent deadEvent) { 199 | deadEvents.add(deadEvent); 200 | } 201 | 202 | } 203 | } 204 | --------------------------------------------------------------------------------