Is is possible to get the reference of a running thread? - java

It was my first post on the community. Any comments and suggestions are welcome.
I have a web service on end point http://ip:port/report. This service execute a Runnable class. After executing the Runnable, is it possible to check / monitor the thread with a separate service call?
I am still working and searching for some stuff like ExecutorService, but still no luck. Is there any other way to do this? Please suggest some probable solution that I can check. Sorry for my grammar. I hope I can explain it clear with my sample code below.
My code is something like this.
Running the thread on : http://ip:port/report
public String runReport {
// Run the the runnable
Report report = new Report();
String threadName = "REPORT1";
Thread t = new Thread(report, threadName);
t.start();
// return thread some details
return t.getId() + "|" + t.hashCode();
}
My runnable class
public class Report {
private String status;
#Override
public void run() {
//Update status
setStatus("Running");
//... do stuff
//Update status
setStatus("End")
}
// Getter and Setter
}
My checker class on http://ip:port/report/check/some_param
public String check( int threadId ) {
// Search the thread by threadId and check the current status
//Report.getStatus();
}

Using thread IDs may not be the best idea, especially because you're likely to use a pool that reuses threads.
A simple solution is to generate IDs for your jobs and maintain a map that you can use to read the status.
As an example, you can use unique IDs for your task IDs:
Map<String, Report> jobs = new ConcurrentHashMap<>();
ExecutorService executorService = Executors.newFixedThreadPool(10); //just an example
public String runReport {
// Run the the runnable
Report report = new Report();
//For a numeric sequence, you can use something like AtomicLong
String jobId = UUID.randomUUID().toString();
jobs.put(jobId, report);
//using a thread pool may be a better idea.
executorService.submit(report);
// return the job ID
return jobId;
}
And to check the status, you just read the map:
public String check(String jobId) {
return jobs.get(jobId).getStatus(); //remember null checks
}
You would then just need to know when to remove entries from the map based on how you expect the check method to be called.

Maintain the map in the class of your job id.
Whenever that thread is initialized, pass the id in the constructor and when it starts processing put the status as running and when it gets completed, just before ending execution in run method, put the status as end. Something like below
public void run(){
try{
jobsMap.put(this.jobId, "Running");
// your business logic here
jobsMap.put(this.jobId,"Completed");
} catch(Exception e){
jobsMap.put(this.jobId,"Failed. Reason -"+e.getMessage);
// exception handling
}
}

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.

Multithreading for array in Java

So, the scenario is like:
//Some code...
public Map<String, String> someFunction() {
for (final UserDetail user : userDetailList) {
// the following (below) code runs in background thread
// long running task
new RecordPersonalisedDao().getPendingRecordsForUid(user.getuId(), new RecordPersonalisedDao.OnResultFetched() {
#Override
public void onResult(Result result) {
// callback after the user is processed
// put some parameter from result to map
map.put(user.getName(), result.getTotal());
}
});
}
// return map only after all users are processed
return map;
}
As mentioned in the comment of above piece of code, I want the final map to be returned only after the entire list of user is processed.
I cannot change the functionality of RecordPersonalisedDao#getPendingRecordsForUid so as to make it run in the main thread only.
How do I achieve this in java ?
Edit: This type of problem can be faced in general. So, I want to understand the solution for the same in java.
To put my question simply, I want behaviour like
Run this code in background for all members in the array, and once it's done, send a callback.
(Roughly like)
[list_of_some_data]
.forEach( run this function )
.after(after the function is run in background for all members of list - return some value)
Before the loop, create a CountdownLatch with a count equal to the user list length. Inside the result handler, count down after updating the map. After the loopawait() the latch to be counted down, then return.
public Map<String, String> someFunction() {
CountDownLatch cdl = new CountDownLatch(userDetailsList.size());
for (final UserDetail user : userDetailList) {
// the following (below) code runs in background thread
// long running task
new RecordPersonalisedDao().getPendingRecordsForUid(user.getuId(), new RecordPersonalisedDao.OnResultFetched() {
#Override
public void onResult(Result result) {
// callback after the user is processed
// put some parameter from result to map
map.put(user.getName(), result.getTotal());
//We're done grabbing the results.. count down.
cdl.countDown();
}
});
}
//Block this thread until all the results are in.
cdl.await();
return map;
}

How to wait for event to happen without blocking?

I'd like my actor to wait for some event to occur, but I want it to still receive messages and proceed with messages. How can I achieve it?
My code is as follows:
class MyActor extends UntypedActor {
//onReceive implementation etc...
private void doSomething(ActorRef other){
String decision = (String) Await.result(ask(other, new String("getDecision"),1000), Duration.create(1, SECONDS));
while(decision.equals(""){
Thread.sleep(100)
decision = (String) Await.result(ask(other, new String("getDecision"),1000), Duration.create(1, SECONDS));
}
}
}
But this blocks entire actor until it receives proper decision. How can I achieve something like that without blocking my actor ?
That kind of code is the good candidate for the use of Futures.
You can find more information here: http://doc.akka.io/docs/akka/snapshot/java/futures.html
In your case, it would look like:
final ExecutionContext ec = context().dispatcher();
private void doSomething(ActorRef other){
Future<Object> decision = (Patterns.ask(other, new String("getDecision"), 1000));
decision.onSuccess(new OnSuccess<Object>() {
public void onSuccess(Object result) {
String resultString = (String) result;
System.out.println("Decision: " + result);
}
}, ec);
}
You should always try to avoid Await.result which like you said causes the thread to block. You can use callbacks such as onSuccess or onComplete to execute code once the future returns without waiting for the result.

How to call a method using multiple threads instead of sequentially

I have a process method in two of my classes which accepts a Map of String.
In the below code, I am using a for loop which will call the process method in two of my classes one by one (sequentially) which is fine.
for (ModuleRegistration.ModulesHolderEntry entry : ModuleRegistration.getInstance()) {
final Map<String, String> response = entry.getPlugin().process(outputs);
System.out.println(response);
}
But is there any way I can launch two thread for this? One thread will call process method of one of my class and second thread will call process method in my second class? And then after getting response from each thread, I want to write to the database. meaning each thread will write to database.
And also there should be timeout feature as well for each thread. We will wait for each thread a specified amount of time, meaning if one of the process method is not returned withing a certain time, then it will get timedout.
Is this possible to do in my use case? If yes, can anyone provide me an example of how to do this? Thanks.
Any help will be appreciated on this.
You can create an ExecutorService with however many threads allocated as you want running, e.g.
ExecutorService executor = Executors.newFixedThreadPool(2)
Now inside of your for loop you would do something like
for (ModuleRegistration.ModulesHolderEntry entry : ModuleRegistration.getInstance()) {
executor.submit(new Runnable () {
public void run() {
final Map<String, String> response = entry.getPlugin().process(outputs);
// write to database
System.out.println(response);
}
}
}
You may also want to have a separate thread handling all of the database writes - your runnables would send their results to it via a BlockingQueue or something along those lines
// Three threads: one thread for the database writer, two threads for the plugin processors
final ExecutorService executor = Executors.newFixedThreadPool(3);
final BlockingQueue<Map<String, String>> queue = new LikedBlockingQueue<>();
Future future = executor.submit(new Runnable () {
public void run() {
Map<String, String> map;
try {
while(true) {
// blocks until a map is available in the queue, or until interrupted
map = queue.take();
// write map to database
}
} catch (InterruptedException ex) {
// IF we're catching InterruptedException then this means that future.cancel(true)
// was called, which means that the plugin processors are finished;
// process the rest of the queue and then exit
while((map = queue.poll()) != null) {
// write map to database
}
}
}
}
for (ModuleRegistration.ModulesHolderEntry entry : ModuleRegistration.getInstance()) {
executor.submit(new Runnable () {
public void run() {
final Map<String, String> response = entry.getPlugin().process(outputs);
// put the response map in the queue for the database to read
queue.offer(response);
}
}
}
// this interrupts the database thread, which sends it into its catch block
// where it processes the rest of the queue and exits
future.cancel(true); // interrupt database thread
// wait for the threads to finish
executor.awaitTermination(5, TimeUnit.MINUTES);

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.

Categories

Resources