Java - Fire an event to another thread on data reception - java

I have to write a server that manages several Datagram sockets.
I know about the selector capabily of java.nio that allows async management of different sockets
However, after having parsed the message I need to fire an event to another thread (optionally with some parameters).
Is there a way to make other threads to "register" to the one that manages the sockets and make them aware that data is ready for them?
Thanks in advance

You can use have an ExecutorService that backs the async network call. The Future returned at that point can act as the message passer upon completion.
public class SocketWork<T>{
private final ExecutorService service = Executors.newSingleThreadExecutor();
private final Future<T> future;
public SocketWork(){
future = service.submit(new SocketWorkCallable<T>());
}
public T register(){
// all threads entering register will block until
// the SocketWorkCallable is completed and returns.
return future.get();
}
}
An alternative is to use a CountdownLatch.
public class SocketWork<T>{
private final CountdownLatch latch = new CountdownLatch(1);
private T message;
public void executeSocketWork(){
//execute work and get message
this.message = returnedMessage;
latch.countDown();
}
public T register(){
latch.await();
return message;
}
}
You could do something similar with a ReadWriteLock as well.
As you can imagine this will only work for a single task. Per instance of SocketWork

Related

Should I use Thread and .join or Callable along with Future and .get?

I am writing a simple thread that simply run a process and reads the InputStream.
While reading the input, if it finds a certain string it sets a boolean to true.
Then when I need to check that boolean I usually do this:
thread.start();
//some other code
thread.join();
thread.getBoolean();
Or should I instead use Callable along with Future? If so, the correct use would be like this?
Callable<Boolean> myTask = new Task();
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<Boolean> future = executorService.submit(myTask);
//some other code
Boolean output = future.get();
System.out.println(output);
executorService.awaitTermination(3, TimeUnit.SECONDS);
executorService.shutdownNow();
In my opinion, it is much better to use interfaces for asynchronous events like this. It is clean, faster and reliable.
Instead of a bare thread class, we would implement a string processor class that has a listener interface, and a process method that would take the stream and as well as the string to look for within the stream. So the approximate implementatin would be as following:
StringProcessor.java
class StringProcessor {
public interface StringProcessorListener {
void onStringProcessingFinish(boolean found);
}
private ExecutorService executorService = Executors.newSingleThreadExecutor();
private StringProcessorListener listener;
public StringProcessor(StringProcessorListener listener) {
this.listener = listener;
}
public void process(InputStream inputStream, String strToFind) {
executorService.execute(()-> {
// Do the processing here...
while(inputStream.availlable() > 0) {
// Processing... maybe some string building or something else...
// Processing code goes here...
// A string built check it out
if(str.equals(strToFind)) {
// The string what we look for is found, notify the listener with true
listener.onStringProcessingFinish(true);
return;
}
// If reached here then the string not found, notify with false
listener.onStringProcessingFinish(false);
}
});
}
}
We would make use of this class from a superior class like following:
YourMainOrSuperiorClass.java
class YourMainOrSuperiorClass {
public static void main(String[] args) {
// Insantiate or get an input stream from where you wish...
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
// Search a string using the processor class
new StringProcessor(new StringProcessorListener {
#Override
public void onStringProcessingFinish(boolean found) {
if(found) {
// The string has been found, handle it
}
else {
// The String has not been found, handle it
}
}
})
.process(bufferedInputStream, "String to find");
// Maybe some more stuff to process from here...
}
}
As you can see, no need to block any thread using async interface patterns. When you invoke the StringProcessor.process() method, it will process the string within its internal thread without blocking the main thread, and you don't have to wait it to finish, on the contrary you can process more code meanwhile.
In the meantime, the StringProcessor will call the listener's onStringProcessingFinish() method as soon as the result is available and it will handled asynchronously from main thread while the main thread is taking care of something else.
Note that main thread should not return until the result is delivered in case of you need to update some UI elements or something else in the main thread. If this is the case you can manage it using a boolean flag, when main thread has been executed all of its stuff then enters to a busy waiting using that flag until the result is delivered. Once the result has delivered you can set that boolean flag accordingly then. It is like some kind of using the thread blocking method stuff.

Kafka Producer Callback performance

I have Kafka Produce which sends the message to kafka .And i log the message in database in the both onsucess and onFailure with the help stored procedure . As shown in the code i am using asynchronous
should i mark my callStoredProcedure method in the repository as synchronised to avoid deadlocks? i believe synchronised is not needed as callback will be executed sequentially in a single thread.
from the below link
https://kafka.apache.org/10/javadoc/org/apache/kafka/clients/producer/KafkaProducer.html
Note that callbacks will generally execute in the I/O thread of the
producer and so should be reasonably fast or they will delay the
sending of messages from other threads. If you want to execute
blocking or computationally expensive callbacks it is recommended to
use your own Executor in the callback body to parallelize processing.
Should i execute callbacks in other thread ?
And can u share the code snippet how to excute callback in other thread. like parallelise callback in 3 threads
My code snippet
#Autowired
private Myrepository myrepository;
public void sendMessageToKafka(List<String> message) {
for (String s : message) {
future = kafkaTemplate.send(topicName, message);
future.addCallback(new ListenableFutureCallback<SendResult<String, String>>() {
#Override
public void onSuccess(SendResult<String, String> result) {
System.out.println("Message Sent " + result.getRecordMetadata().timestamp());
myrepository.callStoredProcedure(result,"SUCCESS");
}
#Override
public void onFailure(Throwable ex) {
System.out.println(" sending failed ");
myrepository.callStoredProcedure(result,"FAILED");
}
});
}
private final ExecutorService exec = Executors.newSingleThreadExecutor();
...
this.exec.submit(() -> myrepository.callStoredProcedure(result,"SUCCESS"));
The tasks will still be run on a single thread (but not the Kafka IO thread).
If it can't keep up with your publishing rate, you might need to use a different executor such as a cached thread pool executor or Spring's ThreadPoolTaskExecutor.

Detecting a timed out Callable instance

I am performing some operations that are time sensitive and have a timeout associated with them.
This timeout mechanism is implemented using the Java Callable class.
The problem is that within the callable instance I execute an asynchronous task, with an anonymous interface implementation (listener).
My problem is that when the timeout triggers and the callable is cancelled. The async callback still executes and corrupts the state of my program.
How do I prevent these callbacks from firing? Do I just include a boolean specififying whether or not the timeout has ocurred or is there another way of achieving this please?
Thanks.
Code reference:
Callable<Object> callableTransaction = new Callable<Object>() {
#Override
public Object call() throws Exception {
Callback callback = new Callback() {
// Do stuff here and change program state.
};
performAsyncOperation(callback);
return ActionProcessor.OPERATION_COMPLETE;
}
};
Why don't you remove performAsyncOperation and perform the operation synchronously inside the call method.
And then, if you need any async operation, you can invoke your callableTransaction using performAsyncOperation or executor services.
Wrap your Callable in a java.util.concurrent.FutureTask... call task.cancel(true) when you want to cancel things. If your Callable is in a blocking operation (I/O, for example), then an exception will be thrown marking the interruption. Otherwise, your thread will need to check using Thread.isInterrupted() periodically to see if it should continue or abort.
Yes, this is mostly the same as including your own boolean flag, but you do get the benefit of blocking operations getting interrupted as well.
You have the right idea: Use a boolean flag to track whether the Callable has been interrupted. (I'm assuming that when you cancel the Callable, you are specifying that it should be interrupted.)
Use a concurrent class like CountDownLatch to make your Callable behave synchronously:
public Object call() throws Exception {
final AtomicBoolean aborted = new AtomicBoolean();
final CountDownLatch latch = new CountDownLatch(1);
Callback callback = new Callback() {
if (aborted.get()) {
return;
}
// Do stuff here and change program state.
latch.countDown(); // Tell Callable we're done.
};
performAsyncOperation(callback);
try {
latch.await(); // Wait for callback to finish.
} catch (InterruptedException e) {
aborted.set(true);
}
return ActionProcessor.OPERATION_COMPLETE;
}

Single Android Thread for Multiple Jobs

I would like to have an application which either loads or saves data through a HTTP request, however the data must interact with the UI thread. Ideally, I would like a single thread to use an IF statement on a message to determine if the request is to "load" or "save".
What would be the simplest way of doing this with the smallest amount of code?
Also, do instances of Handlers run on individual threads?
EDIT: This is the code I am using now:
Handler doStuff = new Handler(){
#Override
public void handleMessage(Message msg){
if(msg.what == 1){
// Load all the information.
// Get the ID from sharedPrefs
SharedPreferences details= getSharedPreferences("details", 0);
String ID = patDetails.getString("id", "error");
// Load up the ID from HTTP
String patInfo = httpInc.getURLContent("info.php?no="+AES.encrypt("387gk3hjbo8sgslksjho87s", ID));
// Separate all the details
patientInfo = patInfo.split("~");
}
if(msg.what == 2){
// Save the data
}
}
};
Eclipse halts the debugging and displays, "Source not found" for StrictMode.class
I suppose it's because it's using the Main thread to access the internet although it's running in individual threads.
Any idea.
Handlers do run on individual threads. Check that link. You should also check out AsyncTask.
I would propose submitting the jobs as Runnable to a single-threaded ExecutorService:
public class SomeClass {
private ExecutorService execService = Executors.newSingleThreadExecutor();
public void doSomething() {
final String someUiData = // retrieve data from UI
execService.submit(new Runnable() {
#Override
public void run() {
// so something time-consuming, which will be executed asynchronously from the UI thread
// you can also access someUiData here...
}
});
}
}
This way, the UI thread will not block whereas you can easily submit a different Runnable for different operations and the ExecutorService will completely take care of keeping it async.
Edit: If you need to interact with the UI, do so before becoming asynchronous and keep the result in final variables.

How to cancel an ExecutorService in java

I wrote an application that runs some threads using ExecutorService and waits until they finish like this:
ExecutorService exService;
exService = Executors.newCachedThreadPool();
exService.execute(T1);
exService.execute(T2);
exService.shutdown();
boolean finshed = exService.awaitTermination(5, TimeUnit.MINUTES);
sometimes I need to cancel the execution of these threads (The entire ExecutorService).
I tried exService.shutdownNow() but it throws java.lang.InterruptedException and doesn't cancel threads.
How can I cancel execution of these threads?
EDIT: T1 class code added as nanda's request
public class TC implements Runnable{
private ExtractedDataBuffer Buffer;
private Scraper scraper;
private String AppPath;
private boolean Succeed=false;
private Map<String,Object> Result=null;
private JLabel StatElement;
public TC(ExtractedDataBuffer Buffer,String AppPath,String XMLfile,JLabel Stat) throws FileNotFoundException {
this.Buffer = Buffer;
this.AppPath=AppPath;
this.StatElement=Stat;
ScraperConfiguration config;
config = new ScraperConfiguration(AppPath + Main.XMLFilesPath +XMLfile);
scraper = new Scraper(config, AppPath);
}
private void extract(){
try{
mainF.SetIconStat("working", this.StatElement);
scraper.execute();
if(scraper.getStatus()==Scraper.STATUS_FINISHED){
this.Succeed=true;
Map<String,Object> tmp=new HashMap<String,Object>();
tmp.put("UpdateTime", ((Variable) scraper.getContext().get("UpdateTime")).toString().trim());
Buffer.setVal(this.Result);
mainF.SetIconStat("done", this.StatElement);
}else{
this.Succeed=false;
this.Result=null;
Buffer.setVal(null);
mainF.SetIconStat("error", this.StatElement);
}
}catch(Exception ex){
this.Succeed=false;
this.Result=null;
Buffer.setVal(null);
mainF.SetIconStat("error", this.StatElement);
}
}
public void run() {
this.extract();
}
}
If you change shutdown() to shutdownNow(), you are doing the correct thing in the code that you wrote. But then, check the documentation of shutdownNow():
There are no guarantees beyond best-effort attempts to stop processing
actively executing tasks. For example, typical implementations will
cancel via Thread.interrupt(), so any task that fails to respond to
interrupts may never terminate.
So probably your T1 and T2 are not coded in a correct way and don't respond to the interrupt well enough. Can you maybe copy the code for them?
--
Based on your code, I guess the code that takes long time is scraper.execute(), right? So inside those method, you have to constantly check something like this:
if (Thread.interrupted()) {
throw new InterruptedException();
}
If the interrupt come, the InterruptedException will be thrown and catched in your catch statement and the thread will stop.
My problem with Future#cancel() is that subsequent calls to get() throw a CancellationException. Sometimes I still want be able to call get() on the Future in order to retrieve a partial result after the shutdown of the executor service. In that case one can implement the termination logic in the callables that you submit to the executor service. Use a field like
private volatile boolean terminate;
public void terminate() {
terminate = true;
}
and check for terminate in the callable as often as required. In addition, you have to remember your callables somewhere so you can call terminate() on all of them.
Use the Executor.submit method, it extends base method Executor.execute(java.lang.Runnable) by creating and returning a Future that can be used to cancel execution and/or wait for completion:
task = Executor.submit( T1 )
...
task.cancel( true )

Categories

Resources