java how to manage callback correctly - java

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.

Related

Java/Android - Proper way to send and receive data at the same time through a socket

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.

What if the computation inside a listener is slow than the listener's update?

I am a new Android programmer. And I am implementing an algorithm within a sensor listener, that each time the sensor data has been received, I will do some computations base on the newly received sensor data, the code is something like this:
class somelistener implements someSensorListener {
public void onReceive(Item state) {
// I will do some computation here, and make a change for the UI
}
}
And now I am wondering a question: what if the computation is slower than the sensor data update frequency, that when the newest sensor data arrives, the last round of computation has not been finished? Will it result in a problem?
Thank you in advance for your answer!
There's 2 case scenarios:
If the callback is asynchronous then it will spawn a new thread every time the method is called. This means that many of these methods can co-exist at the same time.
If the callback is synchronous then it will spawn in the same thread (this is usually the case). In android this usually means that a Looper (http://developer.android.com/reference/android/os/Looper.html) will handle this message as soon as the previous message has finished. If the computation of the method is slower than the rate at which new messages are added to the queue of the Looper, this may eventually throw some kind of exception.
Are you sure that your computation takes more time than the rate of callbacks?

real-time message processing method body in seperate thread

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

How to monitor Asynchronous requests in Java

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?

How to asynchronously read stdin?

Is there an elegant way to fire an event when characters are available from System.in? I'd like to avoid polling InputStream.available().
You would have to create a separate thread that blocks in read until something is available.
If you don't want to actually eat up the input, you would have to wrap it with an internal buffer, read into the buffer, shout, and when asked for the input, give back data from the buffer.
You could solve it like this:
InputStream stdin = System.in;
// Create a wrapper (with it's own dedicated read-thread)
MyListenableInputStream listenableInputStream =
new MyListenableInputStream(stdin);
// Update System.in with something more useful.
System.setIn(listenableInputStream);
Sure...start a thread that blocks on the input and then calls your event method when it gets something.
Very generally speaking:
If you already have an event reactor running, create a thread and have it block on read(). When there's data available, have that thread enqueue an event for the reactor to process. If you can't do this, most event reactors provide an InvokeLater, or CallLater method, for you to run some code in the event processing thread.
After notifying or scheduling a function call, go back to blocking on read().
If you want something elegant you could easily implement an ObservableInputStream which accepts a Listener that gets warned about availability of data but you will have to implement it with an inner thread that periodically checks for data and call the listener in case.
Think about the fact that streams aren't supposed to be used as object that send small packets but a continuous stream of bytes, that's why this approach would work only if the data that is given to the input stream doesn't effectively arrives too often (otherwise it would keep calling the listener ad libitum). In addition you will have to care about consistency, if data arrive when something is already available and the listener is warned then something can take all the bytes (which you should place in a temporary buffer) but if there's more data that just arrived you should decide how to handle (give it together with buffer, place in buffer and call listener again, etc)
new Thread(){
public void run() {
while(System.in.get()){
}
}.start();

Categories

Resources