23 Ocak 2019 Çarşamba

MapMaker Sınıfı

Giriş
Açıklaması şöyle. Şimdiki CacheBuilder yerine eskiden MapMaker kullanılırdır
All caching related methods on MapMaker have been deprecated in favor of similar methods in CacheBuilder, and are scheduled for upcoming deletion. (...)

Most MapMaker use cases should be migrated to either CacheBuilder or  AtomicLongMap. Specifically, cases when MapMaker is used to construct maps with AtomicLong values should generally be migrated to  AtomicLongMap. Other cases where MapMaker caching functionality is used (including all uses of MapMaker.makeComputingMap(Function)) should be migrated to CacheBuilder.
Bu sınıf eğer weakKeys() çağrısı yapılmamışsa altta bir ConcurrentHashMap yaratıyor. Yani aslında bu kullanımda çok faydalı değil. 

Ancak weakKeys() çağrısı yapıldıysa bence önemli bir boşluğu dolduruyor çünkü concurrent olan WeakHashMap + IdendityHashMap birleşimi bir sınıf döndürüyor.
Açıklaması şöyle
Java already supports WeakHashMap to use Weak References for the keys. But, there is no out-of-the-box solution to use the same for the values. Luckily, MapMaker provides simple builder methods to use WeakReference for both the keys and the values.
makeMap metodunun içi şöyle
public <K,V> ConcurrentMap<K,V> makeMap (){
  if(!useCustomMap) {
    return new ConcurrentHashMap<>(getInitialCapacity(), 0.75f, getConcurrencyLevel());
  }
  return MapMakerInternalMap.create(this);
}
concurrencyLevel metodu
Örnek
Şöyle yaparız
 ConcurrentMap<Request, Stopwatch> timers = new MapMaker()
       .concurrencyLevel(4)
       .weakKeys()
       .makeMap();
initialCapacity metodu
Örnek
Şöyle yaparız
ConcurrentMap<User, Session> sessionCache = new MapMaker().initialCapacity(100).makeMap();
mapMap metodu
Örnek
Şöyle yaparız
ConcurrentMap<User, Session> sessionCache = new MapMaker().makeMap();
weakKeys metodu
Açıklaması şöyle. Yani equals() + hashCode() yerine == kontrolü yapılıyor.
If we enable weak references, then MapMaker creates a custom map represented by a set of hash tables internally. It also shares similar performance characteristics as a ConcurrentHashMap.

However, an important difference with WeakHashMap is that the equality checks happen via the identity (== and identityHashCode) comparisons.
Örnek
Şöyle yaparız
ConcurrentMap<User, Session> sessionCache = new MapMaker().weakKeys().makeMap();

17 Ocak 2019 Perşembe

AsyncEventBus Sınıfı

Giriş
Şu satırı dahil ederiz
import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import java.util.concurrent.Executors;
EventBus ile aynı şeydir. Aboneleri asenkron olarak tetikler.

Bi-Directional EventBus
Bu birazcık uğraşarak mümkün. 
Örnek
Elimizde şöyle bir kod olsun
public class AsyncCallDataBean<T> {
  private T response = null;
  private CountDownLatch latch = new CountDownLatch(1);
 
public T getReponse(long timeoutMS) {
  try {
    latch.await(timeoutMS, TimeUnit.MILLISECONDS);
  } catch (InterruptedException e) {
  e.printStackTrace();
  }
  return response;
}
 
  public void setResponse (T response) {
    this.response = response;
    latch.countDown();
   }
}

public class RequestResponseDataBean extends AsyncCallDataBean<String>{
 
  private Object payLoad;
 
  public RequestResponseDataBean (Object payLoad) {
    this.payLoad = payLoad;
  }
 
  public Object getPayLoad() {
    return payLoad;
  }
}
Kullanmak için şöyle yaparız
public class EventBusService {
 
  private static EventBusService instance = new EventBusService();
 
  public static EventBusService $() {
    return instance;
  }
 
  private EventBus eventBus = null;
 
  private EventBusService() {
    eventBus = new AsyncEventBus(Executors.newCachedThreadPool());
  }
 
  public void registerSubscriber(Object subscriber) {
    eventBus.register(subscriber);
  }
 
  public void unRegisterSubscriber(Object subscriber) {
    eventBus.unregister(subscriber);
  }
 
  public void postEvent(Object e) {
  eventBus.post(e);
  }
}

EventBusService.$().registerSubscriber(new MyEventBusSubscriber());
RequestResponseDataBean rrb = new RequestResponseDataBean("Some event payload");
EventBusService.$().postEvent(rrb);
long timeOut = 3000; // wait for 3 seconds before timing out
String result = rrb.getReponse (timeOut);
// will unblock on time out or call to the rrb.setResponse()
constructor - Executor
Açıklaması şöyle.
Executor will be used to dispatch events.
Örnek
Şöyle yaparız.
EventBus eventBus = new AsyncEventBus(MoreExecutors.newDirectExecutorService());
Örnek
Şöyle yaparız
EventBus eventBus = new AsyncEventBus(Executors.newCachedThreadPool());
constructor - Executor + SubscriberExceptionHandler 
Şöyle yaparız.
public class PausableAsyncEventBus extends AsyncEventBus {

  public PausableAsyncEventBus(Executor executor,
                              SubscriberExceptionHandler subscriberExceptionHandler) {
    super(executor, subscriberExceptionHandler);
  }
  ...
}
post metodu
İmzası şöyle
public void post(Object event);
Örnek
Şöyle yaparız.
TargetedDialogStateWrapper wrapper = ...;
clientServerEventBus.post(wrapper);
register metodu
Örnek
Şöyle yaparız
//create an asynch bus in new Thread
EventBus eventBus = new AsyncEventBus(Executors.newCachedThreadPool());

class Transaction {...}

class Receipt {...}
//Listener
class PaymentService {
  @Subscribe
  private void debitBuyer(Transaction transaction) {
    ...
  }
  @Subscribe
  private void creditSeller(Transaction transaction) {
    ...
  }
}
//Listener
class ReceiptSender {
  @Subscribe
  public void sendRecieptToCustomer(Receipt receipt) {
    ...
  }
  @Subscribe
  public void sendRecieptToSeller(Receipt receipt) {
    ...
  }
}

//registering listeners
eventBus.register(new PaymentService());
eventBus.register(new ReceiptSender());

//doing payment proccess
eventBus.post(new Transaction("Buy a ticket", 100D));
//sending message
eventBus.post(new Receipt("Successful transaction"));