Netty - Using the EventLoop to combine operations? - java

I came across this suggestion to combine operations by using the underlying channel's EventLoop to execute them together. In the example provided, write operations are used. It was my assumption was that write operations were already done asynchronously on an I/O thread (the EventLoop?) provided by Netty... so why is it necessary to execute multiple operations using the EventLoop the channel is assigned to?
Also, if doing operations on the EventLoop thread provides some sort of performance benefit then why does that only apply to multiple operations and not single ones?
Any clarification would be appreciated! Thanks.

As I understand when you call this code outside of EventLoop:
channel.write(msg1);
channel.writeAndFlush(msg3);
It under the hood transforms to:
channel.eventLoop().execute(new Runnable() {
#Override
public void run() {
channel.write(msg1);
}
});
channel.eventLoop().execute(new Runnable() {
#Override
public void run() {
channel.writeAndFlush(msg3);
}
});
So for reducing dispatching overhead it is better to combine them to one:
channel.eventLoop().execute(new Runnable() {
#Override
public void run() {
channel.write(msg1);
channel.writeAndFlush(msg3);
}
});

Related

Synchronized method in android

You might think that this question is duplicate of this one but no answers of that question helps me for understanding synchronized method in android. I searched a lot on google for understanding synchronized methods and i found some answer but they didn't help me to perfectly understand Synchronized methods because no answer has any perfect practical example.
I have tried to understand synchronized method by implement 2 synchronized methods in my code and executing them concurrently but i am failed in properly implementing them. So, please provide explanation of synchronized method with simple example so, others like me also can understand it simply and in a faster way.
UPDATE
I am not sure i am going in right direction or not but i have tried following code which have 2 synchronized methods.
synchronized void add() {
counter++;
Log.e("JK", String.valueOf(counter));
}
synchronized void minus() {
counter--;
Log.e("JK", String.valueOf(counter));
}
and i have called this methods in two different threads using below code.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
synchronized (counter++) {
add();
}
}
},500);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
minus();
}
},1000);
Synchronized method is a method which can be used by only one thread at a time.
Other threads will be waiting until the method will be released.
You should have only serious reasons to declare method as synchronized because such method decreases the productivity. The classic case of synchronized method usage is when several threads are using same resources i.e. change state of some object and it is needed to make sure only one thread performs it at a time, otherwise it will cause inconsistency. Also make sure to make synchronized method as small as possible, ideally reduce it to contain only operations which can manipulate common resources.
For example the class Reporter has common resource fileWriter. It writes to file some messages with information about authors.
class Reporter{
private FileWriter fileWriter;
public synchronized void addRecord(String author, String message) throws IOException {
fileWriter.write("\n<<<<<<<<<<>>>>>>>>>>\n");
fileWriter.write("Message written by:" + author + "\n");
fileWriter.write("Message content:" + message);
}
public Reporter(FileWriter fileWriter) {
this.fileWriter = fileWriter;
}
}
Suppose you are running this code from 2 different threads:
Reporter reporter = new Reporter("path/report");
...
Thread thread = new Thread(){
public void run(){
reporter.addRecord("John", "Hi");
}
}
thread.start();
Thread thread2 = new Thread(){
public void run(){
reporter.addRecord("Bill", "Hello");
}
}
thread2.start();
The result for synchronized method will be like this :
<<<<<<<<<<>>>>>>>>>>
Message written by:John
Message content:Hi
<<<<<<<<<<>>>>>>>>>>
Message written by:Bill
Message content:Hello
If method is not synchronized several threads may write to file simultanously, which can cause an unpredictable sequence in file, like this:
<<<<<<<<<<>>>>>>>>>>
<<<<<<<<<<>>>>>>>>>>
Message written by:John
Message written by:Bill
Message content:Hello
Message content:Hi
Synchronized method is a method which can be used by only one thread at a time. Other threads will be waiting until the method will be released. You should have only valid reasons to declare method as synchronized because such method decreases the productivity and performance.

JavaFx new Thread with same Task as input

I am working on a JavaFX desktop application and I have one button that should read from the memory of an embedded device and print that into a JSON. I have implemented a Task that does that, and this Task is passed as argument to a new thread in the button event handler. The problem is, this only works once. After that, even though new threads are generated on button click, the call() method of the Task is never called again. Here is the code:
The Task definition:
Task readValDaemon = new Task<Void>() {
#Override
public Void call() {
//This functions reads from memory and writes the JSON
readDataHI(connection,commandListHI,statusHI);
return null;
}
};
The Thread creation:
readData.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
Thread readValThread = new Thread(readValDaemon);
readValThread.setDaemon(true);
readValThread.start();
}
});
As observed in other answers, a Task is an implementation of FutureTask. From the Task documentation:
As with FutureTask, a Task is a one-shot class and cannot be reused. See Service for a reusable Worker.
So you cannot reuse a task. Second and subsequent attempts to run it will just silently fail.
You could just create a new task directly every time:
private Task<Void> createReadValTask() {
return new Task<Void>() {
#Override
public Void call() {
//This functions reads from memory and writes the JSON
readDataHI(connection,commandListHI,statusHI);
return null;
}
};
}
and then do
readData.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
Thread readValThread = new Thread(createReadValTask());
readValThread.setDaemon(true);
readValThread.start();
}
});
You could also consider using a Service, which is designed for reuse. It basically encapsulates the "create a new task every time" functionality, but adds in a lot of useful UI callbacks. A Service also manages a thread pool for you (via an Executor), so you no longer need to worry that you may be creating too many thread. (The Executor can also be specified, if you want to control it.)
So, e.g.:
Service<Void> readValDaemon = new Service<Void>() {
#Override
protected Task<Void> createTask() {
return new Task<Void>() {
#Override
public Void call() {
//This functions reads from memory and writes the JSON
readDataHI(connection,commandListHI,statusHI);
return null;
}
};
}
};
and then
readData.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
readValThread.restart();
}
});
If the mouse is clicked while the service is already running, this will automatically cancel the already running task, and restart a new one. You could add in checks if you wanted, or bind the disable state of readData to the state of the Service, if you wanted.
Task is kind of the wrong tool for this. It's very purposefully only designed to run once because it's a kind of future. It stores the result (in your case null) as a kind of memoization to avoid doing expensive operations more times than is necessary. So Task is best suited for situations where an expensive computation must be done just once, and usually you would want a result from it at some point down the line.
The documentation for Task is very thorough so I would give that a read.
In your case, just use a plain Runnable. You can use a lambda expression:
readData.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event)
{
Thread readValThread = new Thread(() -> readDataHI(a, b, c));
readValThread.setDaemon(true);
readValThread.start();
}
});
As an aside, creating threads manually isn't considered very good practice in modern Java. Strongly consider an ExecutorService instead.

Threads in JavaFX: do threads need to be killed?

I'm writing an application using JavaFX and my understanding is that, while the UI runs in a thread, all other non-UI operations must run in another. So far, all examples I've found are variations of the following:
myButton.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent a) {
// Some UI operations
new Thread() {
public void run() {
// Some non-UI operations
Platform.runLater(new Runnable() {
public void run() {
// Some operations to update the UI
}
});
}
}.start();
}
});
My question is: do you need to somehow kill the thread in order to release its resources? In the examples I've never nobody seems to use Thread.join or any other similar method.
Also, would it be advisable to use setDaemon like this?
myButton.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent a) {
// Some UI operations
final Thread child = new Thread() {
public void run() {
// Some non-UI operations
Platform.runLater(new Runnable() {
public void run() {
// Some operations to update the UI
}
});
}
};
child.setDaemon(true);
child.start();
}
});
Note:
According to this thread (JavaFX multithreading - joining threads won't update the UI) Thread.join must not be used, but it doesn't seem to address the question of what happens to the threads that are no longer needed or how to kill them.
Threads will age out when there is nothing scheduled for them. However, it is not a good practice to depend on that, as it can take up resources.
The better approach is to use an ExecutorService, such as described in the documentation. A ThreadPoolExecutor can run one or more threads. You can use the same executor to keep submitting runnable tasks, and they will be executed on the threads that it manages. The documentation gives examples on how to shut down the executor service at the end of your application. If you are confident that you have no outstanding tasks being executed, you can issue shutdownNow() to immediately clean up all the threads.

Repeat method in short time interval

I have a activity and I have to update the Views (like Images) every second. I tried a few different methods which I found to implement the same thing. But which of the method is most efficient and reduces memory leak?
Here are the different methods -
Method 1
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
//DO SOMETHING
handler.postDelayed(this, 1000);
}
}, 1000);
Method 2
ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(5);
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
public void run() {
//DO SOMETHING
}
}, 0, 1, TimeUnit.SECONDS);
Method 3
Timer myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
//DO SOMETHING
}
}, 0, 1000);
Which one should I use? I am asking this question because I'm updating my GUI in very short interval of time.
If you want to update values or images on your screen you should use the first method. I solved the same issue by using first method.
Method 1
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
//DO SOMETHING
handler.postDelayed(this, 1000);
}
}, 1000);
Alternative
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(1000);
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
//update here (images or other values)
}
});
}
} catch (InterruptedException e) {
}
}
};
Context
Take into account the fact the Android uses it's own implementation of java.
There is no Java Virtual Machine in the Android platform. Java
bytecode is not executed. Instead Java classes are compiled into a
proprietary bytecode format and run on Dalvik, a specialized virtual
machine (VM) designed specifically for Android. Unlike Java VMs, which
are stack machines, the Dalvik VM is a register-based architecture.
Comparison of Java and Android API
So what holds true for the java virtual machine may not necessarily reflect on Android's implementation.
As a rule of thumbs it's better to use whatever the Android API makes available.
Solution
I recommend using the Handler.
Especially if you want to update views.
Even the official Android tutorials recommends :
To move data from a background thread to the UI thread, use a Handler
that's running on the UI thread.
From the start Timer gets excluded.
There are some disadvantages of using Timer It creates only single
thread to execute the tasks and if a task takes too long to run, other
tasks suffer. It does not handle exceptions thrown by tasks and thread
just terminates, which affects other scheduled tasks and they are
never run
From this answer.
And from the Android docs:
A ThreadPoolExecutor (i.e. ScheduledThreadPoolExecutor) is preferable to Timer when multiple worker threads are needed, or when
the additional flexibility or capabilities of ThreadPoolExecutor
(which this class extends) are required.
When using the Handler i recommend reading through this tutorial if you want to avoid memory leaks.
If it wasn't the case of an UI update a ThreadPoolExecutor would have been better because they provide improved performance when executing large numbers of asynchronous tasks, due to reduced per-task invocation overhead.

Efficient way to implement a continuous thread

I need to keep running a thread which does image processing using the frames from the camera of an android device.
I've tried the simplest way
new Thread() {
#Override
public void run() {
while (true) {
/* Processing frames here */
}
}
}.start();
Buts this hogs the CPU too much and the UI starts lagging. Also, added Thread.sleep(300) after processing the frame so that the UI thread can get some CPU time but although it does help to some extent, it doesn't feel like the right way to do it.
I would like to have some ideas about a good approach to handle this.
EDIT: Using AsyncTask
private DetectionTask detectionTask;
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
/* Doing some stuff here */
camera.addCallbackBuffer(data);
if (detectionTask != null && detectionTask.getStatus() != AsyncTask.Status.FINISHED)
return;
detectionTask = new DetectionTask();
detectionTask.execute();
}
private class DetectionTask extends AsyncTask<Void, Void, float[]> {
#Override
protected float[] doInBackground(Void... params) {
/* Processing frames here */
return result;
}
#Override
protected void onPostExecute(float[] result) {
if (result != null) {
/* Update UI */
}
};
};
Consider using Service instead of Thread. It's a common tool for long-running processes which must do some work time to time on another thread.
If you know exactly when a frame is ready to be processed, you can use the Object.wait() and Object.notify() methods as a simple mechanism to signal your processor thread that a frame is ready.
Object mLock = new Object();
Thread mProcessor = new Thread() {
#Override
public void run() {
while (true) {
mLock.wait();
// do processing
}
}
};
Then call mLock.notify() when a frame or batch of frames is ready.
Have you considered AsyncTask?
It is specially designed just to deal with heavy loads in the background.
It will do the heavy process in the background and update your UI when done.
usually I use Thread. If you are using a device with multi-core processors, the system will automatically dispatch threads to different cores. This means running UI thread and assistant thread simultaneously will be no problem. generally, I save data from Preview callback to a buffer queue in memory, which will not block UI. Then create another thread to read and process the data from the buffer. The buffer queue has to be synchronized. If your data processing takes too much time, you have two options: 1. skip some frames strategically 2. write data to cache file for post-processing. I've done this for my own app.

Categories