I have 2 classes. One (A) collects some data and the other (B) sends the data to TCP/IP clients. The process is asynchronous with refresh rates from nearly zero to a few seconds.
Note that this application has no GUI so I won't be able to use many built in "onChange" listeners.
In normal conditions I would simply write the code so that A calls a "send" method on B, passing the data, no problems here.
Now, assume that the rate A collects data is critical (real time) and that A cannot wait for B to complete the sending process (note that B uses TCP, not UDP). The way I implemented this is
A places the data in a field in B
B has a continuous loop that checks if the data is new or now. If new, it will send it out.
If during the send the data is updated a few times it doesn't matter, as long as it doesn't slow down A.
Spawning a new thread for each send would in principle not slow down A but it's likely gonna result in a mess.
You can see that B is working in synchronous mode (but A isn't) and it's implemented with a while loop with a Thread.sleep() call. My questions are:
Should I use a timer task instead of the while loop? I know that most people hate the Thread.sleep() call but ultimately the only thing I'm interested is in keeping CPU low.
Isn't there a more elegant way than the synchronous approach? In some cases the data refresh of A is about 1 second and it would be nice if I could just have a listener that would act on an event. In such case a sleep time of 25ms would be a waste of cycles. In other cases it's very fast and I'd like no sleep at all.
*Example: imagine that A is submitting screenshots from your screen and B is sending them to the clients. Only the last one matters and B is gonna go as fast as possible *
Any ideas or suggestions? Please keep things as simple and low cpu as possible
thanks a lot!
I would make it like this:
A collects the data in whatever fashion is appropriate and then post the "next message" to send. If there is already a message pending, let the new message replace / update the previous.
B checks for ay pending messages, if one is available it grabs it and send it to the client(s). However, if no message is pending, then B waits for one to be available.
Object lock = new Object();
Object pending = null;
public void post(Object message) {
synchronized (lock) {
pending = message;
lock.notifyAll();
}
}
public Object getNextMessage() {
Object message;
synchronized (lock) {
while (pending == null) {
try {
lock.wait();
} catch (InterruptedException e) {
// Ignore
}
}
message = pending;
pending = null;
}
return message;
}
Using a queue you could instead do
BlockingDeque<Object> queue = new LinkedBlockingDeque<Object>(1);
public void postMessage(Object message) {
// If previous message is still pending we replace it.
queue.clear();
queue.offer(message);
}
public Object getNextMessage() {
while (true) {
try {
return queue.take();
} catch (InterruptedException e) {
// Ignore interrupts
}
}
}
Of course in both example it would be good to instead of the while (true) use a signal so you can gracefully shut down.
I would set up a LinkedBlockingQueue between A and B whose size should not block A when the queue becomes full. In A, the method that collects the data will post it to the queue. In B, as long as there is an item in the queue, it is new and should be sent out.
If you want B to take advantage of multiple edits to a message by A to be merged and sent out as a single update, then I would do it using the Observer.
The message that A keeps updating is the Observable.
B is an observer of this message.
Every time A updates the message, it is an indication for B to take some action.
B can choose to send the update to the clients immediately
B can also choose to wait for a certain period of time using a Timer and send the update to clients only after the timer fires off. The code to send update will be the TimerTask.
B would not set the Timer again until A changes the message.
You can use an Exchanger
B will send information, use the exchanger to exchange (he might wait for A and its fine)
Once exchange is made he will send the information.
A will use the exchanger with timeout 0, which means if B isn't already waiting then we skip this exchange, if he waiting the the exchange will be made and A will continue with his job and B can now send information.
Information that comes while B is busy will be ignore (the exchange in A with timeout 0 will just throw an exception if B is busy, make sure you catch it)
The most elegant way is using a message queue. A writes data to the queue as soon as it is available. B subscribes to the queue and is notified whenever new data is in. A message queue handles everything for you.
However you should be more explicit: should B be notified for each and every message? What happens if an update is lost?
Related
I will try to be clear with my question.
I had a callback function in a class like that, udes to retrieve card information from a reader.
public void CallbackFunction(CardContent PresentedCard) {
}
So normally, i could write my code into this callback function for example if i want to print the content of the card data => this part doesn't take a long time.
But imagine if i want to do a big process that request a long time, like i need to transfert the information in different server so far away => this could take a long time
So what i understand is that during this time if a new card is presented on the reader, i supposed that the callback will be not wake up during this long time, and i will must wait the end of the previous process (send all the data to all the servers) for detecting a new card again.
So my question is what's the best practice to manage this case with a callback function ?
thanks
Use a thread to handle a long-running callback function. The callback function may handle new card events without being blocked.
Here's how to utilise Java's Thread class:
public void CallbackFunction(CardContent PresentedCard) {
Thread thread = new Thread(() -> {
// long-running process here
sendDataToServer(PresentedCard);
});
thread.start();
}
The callback function may handle new card events while transmitting data to the server in this example.
Executor, Future, and CompletableFuture provide extra thread management choices.
The callback function might add card information to a message queue, and a separate thread would process the queue and transmit the data to the server. If necessary, this method may retain event order.
It's also vital to handle problems and exceptions throughout the long-running process and appropriately end or interrupt the thread if the programme is closed or the process takes too long.
I want to know if exists a framework (or any way) to wait for a message inside a java code on asynchronous way. I repeat "asynchronous way".
For example:
int a=5;
MyObject mio= new MyObject();
mio.setx(6);
String message='x|1|5ABC';
MOM.enqueue(message,'myResponseQueue'); // <-- Shoot and forget!!
String res=MOM.dequeue('myResponseQueue'); // instance of class sleep (not in memory) waiting for message.
if (a=mio.getx()){int b=6; } // code awake and continue
a=7;
message='x|2|6ABC';
MOM.enqueue(message,'myResponseQueue'); // <-- Shoot and forget again!!
String res=MOM.dequeue('myResponseQueue'); // instance of class sleep (not in memory) again waiting for message.
if (res!=null){ // <-- code awake again
if (a==5){int b=7;}
}
I know with a Message-Drive Bean i can create a method to wait for the message, but if I have many messages I will break the code in many methods and I will lost the values of the local variables, this makes a very ugly code.
JMS is the java (java-ee) standard way to go. Your requierements are not a problem, you could go with a MDB (and queue) per message type or a single MDB coupled with a strategy pattern to select the appropriate executor per message type.
Otherwise for an event based / reactive framework you can have a look to either akka or RxJava
I'm currently working on an android project that is a sort of P2P application (no central server, IP addresses are entered manually). I've already sorted out how two devices are able to connect to each other, but what I seem to be having trouble figuring out is the best way to send data back and forth with a socket.
Right now, I've got two separate threads, one for sending data, and one for receiving data so that neither attempt blocks the other. My receiving thread checks the output stream, looking for an int until one exists. The int is a flag for the type of data being sent, and depending on that flag, the application prepares to grab the rest of the data, it's all predictable.
My problem comes in when trying to set up the sending thread. I was originally going to have it so that a call on the Sender object (an extension of Thread) would simply send the all the data needed, but realized that doing that didn't actually function within the thread.
Instead, I changed it so that the thread constantly runs and checks for a flag that determines the data going to be sent. A function is called from the UI thread, which prepares the data as class members, and then sets the flag, where it is then "picked up" by the thread and sent off to the other device. However, I realized this would take up a really unnecessary amount of processor time since the loop would be checking the flag over and over.
I'm just wondering what the proper way to do this is since android doesn't allow network operations on the UI thread. Would I have to rewrite the Sender object to create a new thread every time it sends a message?
The Sender thread can be halted via wait(). The Thread can be later resumed by sending it a notify().
An short example for the sender would be:
synchronized(this){
wait();
}
synchronized(sender){
sender.notify();
}
Edit: Obviously, in the above case "this" and "sender" refer to the same Object (the Sender Thread).
Edit2: Clarification where you need to add those statements. Given your description i assume you have something similiar to the following
public void run(){
while(alive){
// synchronized(this){
if (getFlags()!=null){
//send data
setFlags(null);
}
// wait();}
}
}
in your Sender class. With the synchronized and wait you can keep the Thread from consuming all available cpu resources from a core.
Additionally you will need to modify the calling Thread. You will have add the following:
public void handleEvents(..) {
// process the event
// determine what to send
// synchronized(sender) {
sender.setFlags(mydata);
// sender.notify();}
}
Note: If you modify data here that gets accessed in the sender thread you will need to move the synchronized statement further up as this will block the current thread. If the sender blocks too long you might consider queuing the data (e.g. by having Lists of Objects instead of just Objects) and checking a boolean flag before entering the synchronized block.
I'm working on a java SE (+netty) based system that receives messages of different types from clients, aggregates them and pushes aggregated results into storage.
I need to pre-accumulate messages before aggregation until one of two conditions is met - timeout exceeded or quantity exceeded. Timeouts and quantities are pre-configured for each type and may differ greatly. After that, I aggregate/reduce messages of same type and sender and push result into storage. Aggregation may look like calculating average value among messages. Or it may be much more complex. Post-aggregation in storage is not acceptable in my case.
The task seems easy, but I'm stuck with implementation. Obviously I need to collect messages in some data structure and check timeout and quantity rules on each element. I thought about DelayedQueue<Delayed<List<MyMessages>>> (List<MyMessages> - is an aggregatable list of messages).
DelayedQueue implements timeouts in a great way. But it's not clear, how to check maximum quantities and add new messages in Lists effectively. I don't want to check all Lists on every new message, searching for the right one. And it looks not thread safe to add data to Delayed<List> elements.
What data structures/architecture is suitable for the system I'm trying to create? I guess such problem has a proper academic name and solution, what should I google?
Ignoring existing data structures that might help here, the problem can fundamentally be solved in two ways: Either the thread(s) accepting messages performs the checks and notifies the aggregation thread, or the aggregation thread needs to poll. The first approach makes the limit check easy, the second approach makes the timeout easy.
I would suggest combining both: Recieving threads keep track of how many items have been accumulated and notifies the aggregating thread if the threshold has been reached, and the aggregating thread keeps track of the time.
You can do this, simplistically, something like this:
final long maxWait = 1000;
final int maxMessages = 10;
final ArrayBlockingQueue<Message> queue;
final Thread aggregator = new Thread()
{
#Override
public void run() {
try {
ArrayList<Message> messages = new ArrayList<>();
while ( true ) {
messages.clear();
queue.drainTo( messages );
// Store messages
this.wait( maxWait );
}
}
catch ( InterruptedException e ) {
// Handle this..
}
}
};
final Thread reciever = new Thread()
{
#Override
public void run() {
Message message; // Get this from network
queue.put( message );
if(queue.size() > maxMessages) {
aggregator.notify();
}
}
}
This does not handle your message grouping, but I'm sure you can see how this can be extrapolated to handle multiple queues of different message types. To make the aggregator only consider some specific message type when it's notified, you could use some more elaborate messaging mechanism instead of the wait/notify, for instance have it wait on a queue instead, where receiving threads in turn can put queues as "messages" about queues that need to be aggregated and stored.
I have method which is passed in real-time data constantly.
The method then evaluates the data:
void processMessage(String messageBeingPassed) {
//evaluate the message here and do something with it
//depending on the current state of the message
//if message.equals("test")
//call separate thread to save to database etc...
//etc...
}
My question is, is there any advantage to putting the entire method body inside a thread for better performance?
such as:
void processMessage(String messageBeingPassed) {
Runnable runnable = new Runnable() {
public void run() {
//evaluate the message here and do something
//depending on the current state of the message
//if message.equals("test")
//call separate thread to save to database etc...
//etc...
}
//start main body thread for this current message etc...
}
}
Thanks for any response.
It will depend on various factors. If that method is a bottleneck for your application (i.e. you get long queues of messages waiting to be processed), then it will likely improve your performance up to a certain point, and then degrade again if you use too many threads. So you should use a thread pool and have like 4 threads responsible for that, or some other amount that works best.
However, if you don't get such queues of messages, then that's hardly going to help you.
Either way, the only way to know for sure is through testing and profiling of what performs best in your application.
The advantage is that you can process multiple messages at once, and the calling method won't need to block while the message is being processed (in other words, message processing will be asynchronous instead of synchronous). The disadvantage is that you open yourself up to data races / deadlocks / etc if you're not careful about designing your methods - generally, if your runnable will ONLY be operating on the messageBeingPassed object (and not e.g. on any static fields), then you should be fine. In addition, threads carry some overhead with them, which you can reduce by using an ExecutorService instead of constructing your own thread objects.
It's depend on the rate of data and the time taken by the "processMessage". If the next data arrives before the "processMessage" method finishes its execution of the previous data, it is a good idea to use a thread inside the "processMessage" method