Suppose I'm working with the following callback API:
/**
* Registers a new action which will be run at some later time on
* some other thread, clearing any previously set callback action.
*
* #param callback an action to be run later.
* #returns the previously registered action.
*/
public Runnable register(Runnable callback);
I'd like to register my own action, but I want to preserve any set behavior. In other words I'd like my action to look something like:
new Runnable() {
public void run() {
// do my work
originalCallback.run();
}
}
What's the cleanest way to provide originalCallback to my Runnable?
The naive solutions that come to mind risk introducing a window of time where originalCallback isn't available when the callback is called, or that involve some intricate locking.
After some more digging I found Guava's SettableFuture and Java 8's CompletableFuture. I'll leave my BlockingSupplier up for posterity, but either of these Future implementations would be more standard, and work just the same.
You basically need a holder class with a blocking get() method. Something like this:
public class BlockingSupplier<E> implements Supplier<E> {
private final CountDownLatch latch = new CountDownLatch(1);
private volatile E value;
public synchronized void set(E value) {
checkState(latch.getCount() > 0, "Cannot call set more than once.");
this.value = value;
latch.countDown();
}
#Override
public E get() {
latch.await(); // will block until set() is called
return value;
}
}
Then you can use it like so:
BlockingSupplier<Runnable> supplier = new BlockingSupplier<>();
// Pass the BlockingSupplier to our callback
DecoratorCallback myAction = new DecoratorCallback(supplier);
// Register the callback, and set the BlockingSupplier to the old callback
supplier.set(register(myAction));
Where DecoratorCallback's run() looks like this:
public void run() {
// do my work
// This will block until supplier.set() returns
originalCallbackSupplier.get().run();
}
As durron597 mentions there are better ways to design a callback API, but given the API in the question, this seems reasonable.
This is a terrible way to have an API. The Single Responsibility Principle applies here. The way you are doing it now, your runnable is responsible for:
Whatever it's other job is
Calling the other callback.
You are breaking SRP inherently in your API design! Every class that uses this API is already broken from the getgo.
Fortunately, you can easily solve this problem with Guava's ListenableFuture, which works like this:
Submit the task
Get ListenableFuture object back
Attach callbacks with Futures.addCallback
Doing it this way ensures that your system puts the code for managing multithreading and happensBefore relationships in one place, and the code that actually does the work in another.
Related
I have to wait till the HashMap key's value change from another thread and have to continue the request processing after that.
I think the most flexible solution will be to implement the Observer pattern.
Note that build-inn interfaces Observer and Observable are deprecated since JDK version 9. Even if you are using Java 8 don't use them. The problem with them is that their names as well as the method name update() of the Observer don't tell anything to the reader of the code about the event that was triggered and what kind of actions might follow.
Ass you can see from the diagram, the subject should contain a collection of observers (or listeners).
The subject in your case should be class contains a HashMap updates of which you want to listen. Don't extend the map, wrap it with your class instead. Because if you choose to extend HashMap your code will become dependent on its implementation. And any changes in the HashMap, for instance, new methods were added or existing were improved could break your code (this topic is covered in the book "Effective Java" by Joshua Blochtake, have a look at it for more information).
So let's say we have a class OrderManager that maintains a map of Orders. This class will be a subject.
A couple of services like BillingManager, LoggingManagerand maybe some more needs to notified new order was added. These are our ***observers***. All these classes an interface, let's sayOrderAddedListenerthat defines a single methodonOrderAdded(Order order)`, that's the event we are interested in.
Note, if you need to listen to other events like removal or update, you need to define a new interface with a method responsible for that for every target event as the Interface segregation principle suggests.
OrderManager has to have a collection of observers. When a new order is being added, subject iterates through the collection of observers and invokes onOrderAdded() method on each of them.
In order to add an observer that need to listen to the order-added event OrderManager has to define a method to register it, and it's also good practice to add another one to unregister the observer that has registered to be able to remove it when you no longer need it.
Asynchronous processing
Note, that in this example, events are being processing in the same thread. If actions performed by observers are costful or might block the thread, in order to fire them asynchronously you can create a class that will implement Runnable and hold references to the observer and event (order the was added/updated), and method run() will trigger the observer. And when a new event occurs, OrderManager instead of invoking onOrderAdded() on each observer should create a new instance of that class implementing runnable by passing an observer and a new order to its constructor and then create and fire a new thread.
It's a simplified approach. But I guess it'll give an understanding of the general idea.
Implementation example
That how it might look like:
public class OrderManager {
private Map<Long, Order> orderById = new HashMap<>();
private Set<OrderAddedListener> listeners = new HashSet<>();
public void addOrder(Order order) {
// notifying observers
listeners.forEach(observer -> observer.onOrderAdded(order));
orderById.put(order.getId(), order);
}
// more methods like removeOrder(), getOrderCount() etc.
public boolean registerOrderAddedListener(OrderAddedListener listener) {
return listeners.add(listener);
}
public boolean unregisterOrderAddedListener(OrderAddedListener listener) {
return listeners.remove(listener);
}
}
public interface OrderAddedListener {
void onOrderAdded(Order order);
}
public class LoggingManager implements OrderAddedListener {
private Logger logger;
#Override
public void onOrderAdded(Order order) {
// logger.log();
System.out.println("Log message has been written");
}
}
public class BillingManager implements OrderAddedListener {
private BillingService billingService;
#Override
public void onOrderAdded(Order order) {
// billingService.sendBill(order);
System.out.println("A bill has been sent");
}
}
main() - a simple demo
public static void main(String[] args) {
OrderManager orderManager = new OrderManager();
orderManager.registerOrderAddedListener(new LoggingManager());
orderManager.registerOrderAddedListener(new BillingManager());
orderManager.addOrder(new Order());
}
Output
A log message has been written
A bill has been sent
I am newbie in Vert.x.
For example, JDBCClient has non-blocking method
JDBCClient.getConnection(Handler<AsyncResult<SQLConnection>> handler)
When I call it, it is really asynchronous.
jdbcClient.getConnection(result -> { /* this code will execute asynchonous */})
But how can I implement my own component with non-blocking methods?
When I write for example this, it doesnt looks asynchronous. It just will execute method body and then will call passed lambda.
class MyComponent {
public void getSomething(Handler<AsyncResult<String>> handler) {
String result = someHeavyMethodInThisThread();
handler.handle(Future.succeededFuture(result));
}
}
/* later */
/* this code will be blocking, right? */
myComponent.getSomething(res -> { /* ... */ })
Maybe there is way to tell Vert.x that my method should be asynchronous? Some annotation or something else?
There is nothing wrong with your code, your code style, normally will be async because the moment you perform a IO operation or call a vert.x API a async operation will detach you from the current thread (event loop).
In your case you're doing CPU bound code so it does not behave as async and as you stated will just call the lambda. If you want nevertheless make it async you can always wrap your code with runOnContext and that will enqueue it to be run on the next iteration of the event loop, e.g.:
class MyComponent {
public void getSomething(Handler<AsyncResult<String>> handler) {
vertx.runOnContext(v -> {
String result = someHeavyMethodInThisThread();
handler.handle(Future.succeededFuture(result));
});
}
}
I use a method for more than one time in JavaScript by using callback method because JavaScript is an async language.
Example:
function missionOne () {
sumCalculation(1, 2, function (result) {
console.log(result) // writes 3
})
}
function sumCalculation (param1, param2, callback) {
let result = param1 + param2
// The things that take long time can be done here
callback(result)
}
I wonder if there is any way to stop myself in Java?
Edit: I remove several sentences that make more complex the question.
I may be reading too much into your question, but it seems that you're looking into how to handle asynchronous code in Android. There are a couple of native options (not considering any library). I'll focus on two, but keep in mind there are other options.
AsyncTasks
From the documentation
AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
Before writing one, you need to know which type of parameters it will receive, the type of progress it will publish during computation and what is its return type. These types are define via the AsyncTask generic Parameters AsyncTask<Params,Progress,Result>. If you don't need them any of them, set them to Void
Here's the basic gist of using an AsyncTask to compute the sum of two ints:
public void sumCalculation (int param1, int param2, Callback callback) {
new AsyncTask<Integer, Void, Integer>() {
#Override
public Integer doInBackground(Integer... params) {
int result = 0;
for (Integer param : params) {
result += param;
}
return result;
}
#Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
callback.onDone(integer);
}
}.execute(param1, param2);
}
doInBackground, as the name says, will execute a certain piece of code in a background thread. Please note that every AsyncTask will run on a ThreadPool of size 1, so they actually get in the way of other AsyncTasks.
onPostExecute brings the result back to the main thread, so you can update any UI componente. If you try to update the UI from a background thread, an exception will be thrown.
The down side of this particular example is the creation of a new AsyncTask every time that function is called.
Also you should use AsyncTask only if the task won't run for a very long time, couple of seconds at most.
Thread and Handler
Another option suggested on the documentation is using a thread and a handler to communicate between the main thread and a background thread. Although this provides greater flexibility, it also requires more responsibility as you will be responsible for managing the communication yourself, picking the right time to kill your threads and how to recover when something goes bad.
As a rule of thumb, you should only go this way if you really need the extra flexibility.
The overall idea is to create your own Handler and override its handleMessage method.
public class MyHandler {
#Override
public void handleMessage(Message inputMessage) {
int messageType = inputMessage.what;
Object extraData = inputMessage.obj;
...
}
}
public class MyTask extends Thread {
public static public int COMPUTATION_DONE = 0;
private MyHandler handler;
public MyTask(MyHandler handler) {
this.handler = handler;
}
#Override
public void run() {
//do your computation
Message message = handler.obtainMessage(COMPUTATION_DONE, your_result);
handler.sendMessage(message);
}
}
As you can see, this requiring parsing inputMessage.what and deciding what to do with it. Additionally, you need to cast inputMessage.obj to the right type and so on.
These are just two examples, but depending on what you're trying to do, you might need to dig deeper into Services or take a look at some reactive approach, such as RxJava2. However I encourage you to start with the basic before diving into something way more complicated.
Yes it is easy in Java. To take your example above you can write it in Java like this:
public static void main(String[] args) {
System.out.println(sumCalc(1,2));
}
private int sumCalc(int first, int second) {
return first + second;
}
Guava's ListenableFuture library provides a mechanism for adding callbacks to future tasks. This is done as follows:
ListenableFuture<MyClass> future = myExecutor.submit(myCallable);
Futures.addCallback(future, new FutureCallback<MyClass>() {
#Override
public void onSuccess(#Nullable MyClass myClass) {
doSomething(myClass);
}
#Override
public void onFailure(Throwable t) {
printWarning(t);
}}, myCallbackExecutor);
}
You can wait for a ListenableFuture to complete by calling its get function. For instance:
MyClass myClass = future.get();
My question is, are all callbacks for a certain future guaranteed to run before the get terminates. I.e. if there is a future with many callbacks on many callback executors registered, will all the callbacks complete before get returns?
Edit
My use case is, I pass a builder around to many classes. Each class populates one field of the builder. I want all fields to be populated asynchronously because each field requires an external query to generate the data for the field. I want the user who calls my asyncPopulateBuilder to receive a Future on which she can call get and be assured that all the fields have been populated. The way I thought to do it is as follows:
final Builder b;
ListenableFuture<MyClass> future = myExecutor.submit(myCallable);
Futures.addCallback(future, new FutureCallback<MyClass>() {
#Override
public void onSuccess(#Nullable MyClass myClass) {
b.setMyClass(myClass);
}
#Override
public void onFailure(Throwable t) {
printWarning(t);
}}, myCallbackExecutor);
}
// Do the same thing for all other fields.
What is the recommended way to block until all fields are populated in such a case?
Callbacks are not guaranteed to run before get returns. More on that below.
As for how to address this use case, I would suggest turning the query for each field's data into a separate Future, combining them with allAsList+transform, and taking action on that. (We may someday provide a shortcut for the "combine" step.)
ListenableFuture<MyClass> future = myExecutor.submit(myCallable);
final ListenableFuture<Foo> foo =
Futures.transform(
future,
new Function<MyClass, Foo>() { ... },
myCallbackExecutor);
final ListenableFuture<Bar> bar = ...;
final ListenableFuture<Baz> baz = ...;
ListenableFuture<?> allAvailable = Futures.allAsList(foo, bar, baz);
ListenableFuture<?> allSet = Futures.transform(
allAvailable,
new Function<Object, Object>() {
#Override
public Object apply(Object ignored) {
// Use getUnchecked, since we know they already succeeded:
builder.setFoo(Futures.getUnchecked(foo));
builder.setFoo(Futures.getUnchecked(bar));
builder.setFoo(Futures.getUnchecked(baz));
return null;
}
}
};
Now the user can call allSet.get() to await population.
(Or maybe you want for allSet to be a Future<Builder> so that the user is handed a reference to the builder. Or maybe you don't need a full-on Future at all, only a CountDownLatch, in which you could use addCallback instead of transform and count down the latch at the end of the callback.)
This approach may also simplify error handling.
RE: "Do callbacks run before get?"
First, I am pretty sure that we don't guarantee this anywhere in the spec, so thanks for asking rather than just going for it :) If you do end up wanting to rely on some behavior of the current implementation, please file an issue so that we can add documentation and tests.
Second, if I take your question very literally, what you're asking for isn't possible: If get() waits for all listeners to complete, then any listener that calls get() will hang!
A slightly more lenient version of your question is "Will all the listeners at least start before get() returns?" This turns out to be impossible, too: Suppose that I attach two listeners to the same Future to be run with directExecutor(). Both listeners simply call get() and return. One of the listeners has to run first. When it calls get(), it will hang, since the second listener hasn't started yet -- nor can it until the first listener is done. (More generally, it can be dangerous to rely on any given Executor to execute a task promptly.)
A still more lenient version is "Will the Future at least call submit() for each of the listeners before get() returns?" But this ends up with a problem in the same scenario as I just described: Calling submit(firstListener) on a directExecutor() runs the task and calls get(), which can't complete until the second listener is started, which can't happen until the first listener completes.
If anything, it's starting to sound much more likely that get() will return before any listeners execute. But thanks to the unpredictability of thread scheduling, we can't rely on that, either. (And again: It's not documented, so please don't rely on it unless you ask for it to be documented!)
final Builder b;
CountDownLatch latch = new CountDownLatch(1);
ListenableFuture<MyClass> future = myExecutor.submit(myCallable);
Futures.addCallback(future, new FutureCallback<MyClass>() {
#Override
public void onSuccess(#Nullable MyClass myClass) {
b.setMyClass(myClass);
latch.countDown();
}
#Override
public void onFailure(Throwable t) {
printWarning(t);
latch.countDown();
}, myCallbackExecutor);
try {
latch.await();
} catch (InterruptedException e) {
LOG.error("something InterruptedException", e);
} finally {
myCallbackExecutor.shutdown();
}
Edit
code is inspired by #Chris Povirk
(Or maybe you want for allSet to be a Future so that the user is handed a reference to the builder. Or maybe you don't need a full-on Future at all, only a CountDownLatch, in which you could use addCallback instead of transform and count down the latch at the end of the callback.)
This approach may also simplify error handling.
There are two good (as considered by most) java practices that i try to combine and fail.
Never leak this in a constructor.
Use enum instead of singleton pattern.
So, I want a singleton that as soon as created, listens for some event. Here's an example. First, the event listener interface:
public interface EventListener {
void doSomething();
}
Then, the event producer:
public class EventProducer implements Runnable{
private EventListener listener;
public EventProducer(EventListener listener) {
if (listener == null) {
throw new NullPointerException("Listener should not be null.");
}
this.listener = listener;
}
#Override
public void run() {
listener.doSomething(); //This may run before the listener is initialized.
do {
long startTime = System.currentTimeMillis();
long currentTime;
do {
currentTime = System.currentTimeMillis();
} while ((currentTime - startTime) < 1000);
listener.doSomething();
} while (!Thread.currentThread().isInterrupted());
listener = null; //Release the reference so the listener may be GCed
}
}
Then, the enum (as the 2nd listed java practice suggests):
public enum ListenerEnum implements EventListener{
INSTANCE;
private int counter;
private final ExecutorService exec;
private ListenerEnum() {
EventProducer ep = new EventProducer(this); //Automatically unregisters when the producer is done.
counter = 0;
exec = Executors.newSingleThreadExecutor();
exec.submit(ep);
}
#Override
public void doSomething() {
System.out.println("Did something.");
counter++;
if (counter >= 5) {
exec.shutdownNow();
}
}
}
And finally, something to get things started:
public class TestRunner {
public static void main(String[] args) {
ListenerEnum.INSTANCE.doSomething();
}
}
The problem lies in the first line of the ListenerEnum constructor, as we are leaking this, thus not conforming to the 1st listed java practice. This is why our event producer can call a listener's method before the listener is constructed.
How do I deal with this? Normally I would use a Builder pattern, but how is that possible with an enum?
EDIT:
For those that it matters, the event producer in my program actually extends a BroadcastReceiver, so my enum cannot be the event producer, they have to be separate. The producer is created in the constructor of the enum (as the example) and is registered programmatically later on. So I don't actually have a problem leaking this. Nevertheless, I'd like to know if I could avoid it.
EDIT 2:
Ok, since there are suggestions to solve my problem, i'd like to clarify some things. First of all, most suggestions are workarounds. They suggest doing the same thing in a completely different way. I appreciate the suggestions, and probably will accept one as answer and implement it. But the real question should be "How do i implement a Builder pattern with an enum?" The answer i already know and people suggest is "You don't, do it some other way.". Is there anyone who can post something like "You do! You do it this way."?
I was asked to give code close to my actual use case. Modify the following:
public enum ListenerEnum implements EventListener{
INSTANCE;
private EventProducer ep;
private int counter;
private ExecutorService exec;
private ListenerEnum() {
ep = new EventProducer(this); //Automatically unregisters when the producer is done.
counter = 0;
}
public void startGettingEvents() {
exec = Executors.newSingleThreadExecutor();
exec.submit(ep);
}
public void stopGettingEvents() {
exec.shutdownNow();
}
#Override
public void doSomething() {
System.out.println("Did something.");
counter++;
if (counter >= 5) {
stopGettingEvents();
}
}
}
As well as this:
public class TestRunner {
public static void main(String[] args) {
ListenerEnum.INSTANCE.startGettingEvents();
}
}
Now all i have to do to solve my problem is move the EventsProducer creation to the startGettingEvents() method. That's it. But that is also a workaround. What i'd like to know is: In general, how do you avoid leaking this in the constructor of a listener enum since you can't use the Builder pattern? Or can you actually someway use the Builder pattern with an enum? Is it done only by workarounds in a case by case basis? Or is there a general way to deal with this that i don't know of?
Just create a static initialization block:
public enum ListenerEnum implements EventListener{
INSTANCE;
private int counter;
private static final ExecutorService exec; //this looks strange. I'd move this service out of enum.
private static final EventProducer ep;
static{
exec = Executors.newSingleThreadExecutor();
ep = new EventProducer(INSTANCE); //Automatically unregisters when the producer is done.
exec.submit(ep);
}
#Override
public void doSomething() {
System.out.println("Did something.");
counter++;
if (counter >= 5) {
exec.shutdownNow();
}
}
}
As long as enum values are final and static they are initialized before the static initialization block. If you decompile the enum you'll see a single initialization block:
static{
INSTANCE = new ListenerEnum();
exec.submit(INSTANCE.ep);
}
First, consider why this shouldn’t escape:
You loose the final field safe publication guaranty in case of an improper publication of the instance
Even with a safe publication there are inconsistencies regarding all action not performed within the constructor at the time of the leakage
You will let escape an incomplete instance in case of subclasses as the subclass’ constructor hasn’t been called so far
That doesn’t apply to you in this narrow case. Submitting to an Executor is not an improper publication and enum’s can’t escape in any other way besides the one you have implemented yourself in the constructor. And its the last thing in the constructor whereas enums can’t have subclasses.
Now that you have edited your question, it makes much lesser sense. The constructor
private ListenerEnum() {
ep = new EventProducer(this);
counter = 0;
}
is not a “leaking this” as long as ep is not a static variable and the constructor of EventProducer does not let leak its this as well. This is important as programmers must be able to create circular object graphs without fearing sudden inconsistencies.
But it is still nothing you should take too easy. As said, it relies on the behavior of the EventProducer regarding leakage and regarding that EventProducer must not call back into ListenerEnum which could break things without being a “leaking this”, technically. After all, you can create code that breaks without breaking thread safety.
So it’s code for which you can’t see the correctness when looking at it as you need knowledge about another class.
There are use cases where passing this to another object is considered safe because of well-known behavior, e.g. weakThis=new WeakReference(this); is a real-life example. However, passing this to something called EventProducer is likely to let alarm bells ringing for every reader which you should avoid even if you know for sure that it’s false-alarm.
However, the big design smell lies in the use of the Singleton pattern in itself. After all, every instance you create is unique in the first place. What is special about the Singleton pattern is that it provides global public access to that instance. Is that really what you want? Did you consider that by using the Singleton pattern, everyone inside the entire application could register that listener again?
The fact that your class is a singleton (whether enum-based or otherwise) is unrelated to your problem. Your problem is simply how to register a listener within the constructor of an object. And the answer is: it's not possible, safely.
I would recommend you do two things:
Ensure your listener doesn't miss out on events by having a queue that it polls for work. This way, if it temporarily isn't listening, the work just queues up. In fact, this means it doesn't really need to be a listener in the traditional sense. It just needs to poll on a queue.
Register the class as a listener using a separate method, as discussed in the comments.
I would give some thought to avoiding a singleton. It doesn't offer many advantages (asides from the minor benefit of being able to call SomeClass.INSTANCE from anywhere). The downsides are most strongly felt during testing, where you find it much harder to mock the class when you wish to test without actually sending things over the network.
Here's a concrete example of why leaking this is dangerous in your case. Your constructor passes this before setting counter to zero:
private ListenerEnum() {
ep = new EventProducer(this);
counter = 0;
}
Now, as soon as this escapes, your event producer might invoke doSomething() 5 times before the constructor completes:
#Override
public void doSomething() {
System.out.println("Did something.");
counter++;
if (counter >= 5) {
exec.shutdownNow();
}
}
The sixth call to this method ought to fail right? Except that your constructor now finishes and sets counter = 0;. Thus allowing the producer to call doSomething() 5 more times.
Note: it doesn't matter if you reorder those lines as the constructor may not be executed in the order it appears in your code.