I want to implement a design in Java where I have multiple event sources (Threads). Such event source accomplish a specific task and had to notify the unique Event Handler (Class) and this one have to accomplish other tasks according to event sources notifications.
My question is : how to implement this desiqn in the appropriate manner in Java?
There is a design pattern similar to this design?
Thank you in advance :).
I think you are looking for the Observer pattern. Java does have some standard interfaces (java.util.Observer, java.util.Observable), though these are not type specific; so you might consider your own if the domain seems to require it.
class MyThread implements Runnable {
Observable observable;
public MyThread(EventHandler observer) {
observable = new Observable();
observable.addObserver(observer);
}
public void run() {
while (!done()) {
Object result = doStuff();
observable.notifyObservers(result);
}
}
}
// might have this be singleton
class EventHandler implements Observer {
public synchronized void update(Observable o, Object arg) {
accomplishOtherTask();
}
}
Sounds like an actor pattern to me. Each thread acts as an actor, accomplishing one single task. Th eoutcome is set on a queue (yes) to be processed by the next actor.
I have no experience with java actor frameworks, though. Consult Google for that.
In GWT, this is called the event bus. Either GWT.HandlerManager or GWTx.PropertyChangeSupport are Google recommended implementations. The latter is available in J2SE since 1.4.2
Maybe I don't understand your question, but I think you don't need any design pattern, but something from the java.util.concurrent package.
A ThreadPoolExecutor ?
Observable pattern doesn't have an opinion over threading. In EventThread pattern the listener can state in what thread and when is the event handled.
public class MyObservableObject {
...
void addListener(MyListener listener, Executor executor);
}
public interface MyListener {
void onEvent(Object sender, Object event);
}
// Example
obj.addListener( myListener, CURRENT_THREAD );
obj.addListener( myListener, myWorkQueue );
obj.addListener( myListener, AWT_EDT ); // or SWT_EDT
obj.addListener( myListener, Executors.newSingleThreadScheduledExecutor() );
Related
The features mentioned in title serve a simple purpose: allow an user to bind some event listeners to an object which will dispatch all event listeners when event occurs.
This simple concept can, of course, achieved like this:
public class EventEmitter extends ArrayList<Runnable>;
But I would prefer a smarter emitter - ideally one that allows arguments to be passed to the callback. Runnable does not have any arguments of course. Lambda expressions do have parameters on the other side.
Smart emitters allow you to define specific callback parameters:
EventEmitter<String, Boolean> emitter = new EventEmitter();
My question whether this thing is part of java library or if I have to implement it myself. On google, I only found some java.awt.AWTEvent but that is not event dispatcher.
My preferred pseudo code:
// Requires lambdas with (File, int) signature
public final EventEmitter<File, int> downloadCompleteEvent;
And new events added as:
downloaderClass.downloadCompleteEvent
.addListener(
(File file, int downloadTime)->System.out.println("Downloaded "+file.getAbsolutePath()+" in "+downloadTime+" seconds.")
);
And dispatch events as:
this.downloadCompleteEvent.dispatch(downloadedFile, elapsedTime);
In pure Java, you can use a CompletableFuture which represents a state or a work currently in action. On a completable future, you can add one or more listeners which will be invoked with result.
by example:
public CompletableFuture<DownloadResult> download() {
// computing a result async
CompletableFuture<DownloadResult> future = CompletableFuture.supplyAsync(/* your process*/);
return future;
}
future.thenAccept( (DownloadResult) r -> { ... } );
// will be called when process is done
Also, you can be interested by EventBus into Guava library: https://github.com/google/guava/wiki/EventBusExplained
Or by RXJava library: https://github.com/ReactiveX/RxJava/wiki/How-To-Use-RxJava
Some libraries may have a class that can be extended to add this functionality, but it is not a native java idiom. If you want this functionality you need to track and notify event listeners yourself via the observer pattern.
After reading an interesting article, I have a few questions around this. Please refer to Common Pitfall #8: Pretending Java is more like C (i.e. not understanding OOP) on [zero-turn-around]
I agree to the authors solution for the pitfall. I face a similar issue with my code (abuse of instanceof). But I cannot implement the code as the author has suggested. My scenario is as below
I have JMS as a messaging bus.
Messages float around the system. Listener typically listen to the messages.
All the messages have a single parent IMessage.
I use instanceof to distinguish between messages.
The listeners typically do domain specific business logic.
If I agree with the authors solution, I will have to implement domain specific business logic in the Message classes, which I think will bloat my light-weight message objects. Not just that, I will now have many references (composition) in my message objects which I think is unfair as the message objects will now have business (domain) behavior in it.
What is the reasonable solution to this problem? Example code below
public void onMessage(IMessage mssg)
{
if(mssg instanceof MoPn){
...
} else if(mssg instance of MoZn){
...
} else if(mssg instance of MoLn){
...
}
}
One reasonable solution is creating listeners that know to work with specific type of message.
Here is the interface.
interface MessageListener<M extends IMessage> {
void onMessage(M message);
}
Here is a skeleton of one of the classes:
class MoZnListener implements MessageListener<MoZn> {
public void onMessage(MoZn message) {
}
}
Now you can create mapping between messages and listeners. You can use properties file, hard coded map, annotations. It is up to you. Once you have it you can implement one JMS message listener that looks like
class MessageEntryPoint implements MessageListener {
public void onMessage(Message message) {
getMessageHandler(message).onMessage(message.getObject());
}
}
Now your system is extandable. No instanceof. To introduce new message type you just have to create appropriate class that implements IMessage and listener that supports it.
BTW more comments.
Using I as to mark interface is not java-style.
I am not familiar with your domain and probably name like MoPn is self-explainable for you, but IMHO it is not. Try to use more self explainable identifiers.
This might upset some purists, but I believe that using a language with OO features doesn't necessarily mean you have to apply OO to everything.
Messages are simply schema. They carry data. Forcing object-orientation upon structures that merely carry data from one place to another can be an anti-pattern as well.
Separating the logic from the data model is sometimes seen as being against OOP but is sometimes necessary for decoupling. The code sending the message doesn't need to know anything about how to respond to the message.
Some of the other problems with instanceof are that it's hard to find what needs updating when adding a new type, and there's no way to make sure all cases are covered. These problems can be solved by adding some new interfaces:
interface Message {
void callHandler(MessageHandler handler);
}
interface MessageHandler {
default void onMoPn(MoPn message) {
}
default void onMoZn(MoZn message) {
}
}
class MoPn implements Message {
public void callHandler(MessageHandler handler) {
handler.onMoPn(this);
}
}
class Mozn implements Message {
public void callHandler(MessageHandler handler) {
handler.onMoZn(this);
}
}
and add a handler:
class MessageHandlerImpl implements MessageHandler {
public void onMoPn(MoPn message) {
System.out.println("MoPn message: " + message);
}
}
When you get a message, you can call the handler like:
MessageHandler handler = new MessageHandlerImpl()
Message message = new MoPn();
message.callHandler(handler);
I'm writing radio player on android. I want to use RDS fucntion and display text in GUI. I have object that manage radio and its functions. When something changes, like RDS text, i want publish it in simple TextBox inside Activity. How i can notify GUI that one of property has changed (and send new value) and i have to refresh that property? Is there any mechanism inside Android that provide such asynchronous notification functionality? I've read about
PropertyChangeListener but this is mechanizm for JavaBeans, can I adopt that? If yes, tell me how i can register and use change listeners in my case.
You can use the Observer Design Pattern
You can use Handler for this job. Here is some examples:
https://developer.android.com/training/multiple-threads/communicate-ui.html
http://www.techotopia.com/index.php/A_Basic_Overview_of_Android_Threads_and_Thread_handlers
Cheers
Create a class like this:
abstract class RDSTextListener {
public abstract void onRDSTextChanged(String newText);
}
From your activity do something like:
RDSTextListener listener = new RDSTextListener() {
public void onRDSTextChanged(String newText) {
runOnUiThread(new Runnable() {
#Override
public void run() {
((TextView)findViewById(R.id.your_text_view)).setText(newText);
}});
}
}
You will have to pass this listener to your business class. The business class will then call onRDSTextChanged() when its appropriate, and the UI will be updated.
EDIT: Note, this doesn't use interfaces. An abstract class instead. I think that's more Android friendly, avoiding needlessly processing power.
I've been trying to make multiple Presenters "listen" to the same event but I which to make each event unique to the Presenter.
Ex.
I create 3 Composite widgets each in one different tab. They get all attached to the same event at binding. Let's call it the "NewPrescriptionEvent". If this event is fired, all my 3 composites will try to DO the job. I only want one of them to do it.
The only way I found to do this is by creating a temp event id (an integer inside the event) which I check for each widget which is trying to respond to the event.
Code snippet
private class OnNewPrescription implements NewPrescriptionHandler {
#Override
public void onNewPrescription(NewPrescriptionEvent event, int dataObjectId) {
if (getDataObject().getPatientId() == dataObjectId) {
...
}
}
}
During binding I do the usual:
eventBus.addHandler(NewPrescriptionEvent.TYPE, new OnNewPrescription());
The event:
public class NewPrescriptionEvent extends GwtEvent<NewPrescriptionHandler> {
public static final GwtEvent.Type<NewPrescriptionHandler> TYPE = new GwtEvent.Type<NewPrescriptionHandler>();
private int dataObjectId;
public NewPrescriptionEvent(int dataObjectId) {
this.dataObjectId = dataObjectId;
}
#Override
protected void dispatch(NewPrescriptionHandler handler) {
handler.onNewPrescription(this, dataObjectId);
}
#Override
public GwtEvent.Type<NewPrescriptionHandler> getAssociatedType() {
return TYPE;
}
}
I was thinking that the TYPE need to be different each time but still be the same event. Does anyone have a suggestion?
Thx.
Is it the case that you have an arbitrary number of instances of the same presenter and all are listening to the same event type? And each of your presenters 'controls' a different entity an therefore should only react on events coming from that entity? If that's the case the only solution I see is to parametrize the event as you've done.
Sounds like the EventBus probably isn't the best approach here; this is one of the main problems I've personally had with the EventBus: all events are global, and it's hard to differentiate between different events of a given type.
A good set of rules for asynchronous event handling without a shared EventBus is:
Communicate with child widgets via direct method calls.
Communicate with a parent widget via callbacks/handlers/listeners.
Avoid direct knowledge of sibling widgets (probably beside the point here)
So, the widget that contains the 3 tabs can attach callbacks to each tab that, when called, dispatches each event to its appropriate event handler (Presenters, in your case, I believe).
No global communication required, no knowledge of sources or destinations, only one event type, one reusable tab widget type, and the tab class stays simple. In principle, not too different from adding a ValueChangeHandler to a CheckBox (after all, one doesn't subscribe to check box events via the event bus, you just add a handler directly to the widget).
Rough sketch:
public class TabContainer implements IsWidget {
public TabContainer() {
tab1.addNewPrescriptionHandler(
new NewPrescriptionEventHandler() {
#Override
public void handleNewPrescriptionEvent(NewPrescriptionEvent event) {
handleTab1Event(event);
}
});
tab2.addNewPrescriptionHandler(
new NewPrescriptionEventHandler() {
#Override
public void handleNewPrescriptionEvent(NewPrescriptionEvent event) {
handleTab2Event(event);
}
});
...
}
}
And you might even be able to simplify that with some looping and pairing.
Going the other way, this container can also send events back the other way to your widgets from wherever else using the same principles.
Also, depending on what the Event class contains, you might not even need an Event class; you can define your callbacks and params however you want.
I think the title of the question is your answer.
You need different event types for each of the widgets.
You could try using addHandlerToSource(GwtEvent.Type<H> type, Object source, H handler) if you know the source to listen to.
Another possibility would be to extend EventBus to accept some kind of filter on registration.
For some of HTTP requests from clients, there're very complex business logic in server side.
Some of these business logics doesn't require to response to the client immediately, like sending a email to somebody. Can I put those tasks in an asynchronous method,so I only need to ensure that they had been executed,I don't need to wait all tasks complete to respond to the user.
Updated: Some people asked about the framework I am using. I am using Struts2 + Spring.
You can use the following 'fire and forget' pattern:
new Thread(new Runnable(){
public void run(){
System.out.println("I Am Sending Email");
sendEmailFunction();
}
}).start();
But too many such threads will lead to trouble. If you are going to do this, then you should use a ThreadPoolExecutor to ensure that you have some control over thread production. At the very least, place a maximum on the number of threads.
I don't know what framework you're using, but, in basic Java, you can just create a new Thread:
interface MyTaskCallback {
void myTaskCallback();
}
class MyTask implements Runnable {
MyTaskCallback callback;
Thread me;
public MyTask(MyTaskCallback callback) {
this.callback = callback;
this.me = new Thread();
}
public void start() {
this.me = new Thread(this);
this.me.start();
}
public void stop() {
try {
this.me.join(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
// Calls here will not block the other threads
sendEmailRequest();
callback.myTaskCallback();
}
}
class Main implements MyTaskCallback {
public void foo() {
MyTask m = new MyTask(this);
m.start();
}
public void myTaskCallback() {
// called when MyTask completes
}
}
Yes. Read about concurrency.
You can probably set up an asynchronous producer/consumer queue, for example.
there is no "asynchroneous method" in java, but you will either use Threads (possibly through a framework like Quartz: http://www.quartz-scheduler.org/ ) or a message queue like JMS http://java.sun.com/products/jms/
You want to look at the java.util.concurrent.Executors. One way to solve your problem is to have a ScheduledExecutorService which keeps a Queue, and runs every so often. There are many different ways to offload work available in the concurrent utilities however, it depends on your requirements, how expensive the tasks are, how fast they need to be done, etc.
You should respond to all HTTP requests immediately, otherwise the client may think the server is not responding or timeout. However, you could start up other threads or processes to complete tasks in the background before you respond to the client.
You could also continue to send 100 responses until the task was complete.
Yes you can Servlet 3.0 has great asynchronous support.
Watch this its a really great resource, you can watch the entire cast if you are unfamiliar with Servlet 3.0.
A good run down of it here.
The api docs.
Spring has good support for Quartz scheduling as well as Java Threading. This link will give you better idea about it.
Can I put those tasks in an asynchronous method,so I don't need to wait all tasks complete to respond to the user ?
YES