Multithreading for array in Java - 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;
}

Related

Execute two threads in parallel and restart the first one when it ends instead of waiting for both to finish

I have two methods in Java and I execute them in parallel in a class which has a fixed delay. The first thread takes a few minutes to complete, while the second one can take some hours. What I want is to restart the first thread and execute it when it ends, instead of waiting for the second one to finish and re-execute both of them.
Can anyone help me with this?
My code is below:
#Scheduled(fixedDelay = 30)
public void scheduled_function() throws IOException, InterruptedException {
Callable<Void> callableSchedule = new Callable<Void>()
{
#Override
public Void call() throws Exception
{
getAndUpdateSchedule();
return null;
}
};
Callable<Void> callableMatches = new Callable<Void>()
{
#Override
public Void call() throws Exception
{
processMatches();
return null;
}
};
//add to a list
List<Callable<Void>> taskList = new ArrayList<Callable<Void>>();
taskList.add(callableSchedule);
taskList.add(callableMatches);
//create a pool executor with threads
ExecutorService executor = Executors.newFixedThreadPool(2);
try
{
//start the threads
executor.invokeAll(taskList);
}
catch (InterruptedException ie)
{
System.out.println("An InterruptedException occured");
}
You can just store a boolean variable, let's call it isComplete, that stores whether the long task has completed or not. This will be an instance variable, since we need it to stay around after scheduled_function() returns. Something like this:
private boolean isComplete = false;
Now, right now this variable is meaningless because we never update it. So, we need to make sure to update this variable when the long task completes:
Callable<Void> callableMatches = new Callable<Void>()
{
#Override
public Void call() throws Exception
{
processMatches();
synchronized (MyClass.this) { // MyClass is just a placeholder name
isComplete = true;
}
return null;
}
};
Notice that where I update the isComplete variable, I put it in a synchronized block. This ensures that the value we are writing is actually going to be updated on the other thread, and it prevents the other thread from reading while we're writing the value. The result is that the other thread always gets the updated value.
This bit is tangential to the answer, but we can actually shorten this piece of code significantly by using lambda syntax. Callable is a functional interface, so this is perfectly legal:
Callable<Void> callableMatches = () -> {
processMatches();
synchronized (MyClass.this) { // MyClass is just a placeholder name
isComplete = true;
}
return null;
};
Now all we have to do is check this variable every time we want to start the short task. Since we only have 2 threads, and one of the threads is being used for the long task, we know that this task will always be executed on the same thread. This means there's no point in going back to the executor, we can just put it in a while loop inside the callable. On every iteration of the while loop, we just need to check our isComplete variable, and we'll break out of the loop if the other task has completed.
Callable<Void> callableSchedule = () -> {
while (true) {
synchronized (MyClass.this) { // MyClass is just a placeholder name
if (isComplete) {
break;
}
}
getAndUpdateSchedule();
}
return null;
};
Note that in this example, I've used the lambda syntax and I've put the if statement inside another synchronized block. As I explained above, we don't want to get a stale value here and keep looping after the other task is complete.

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

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
}
}

Refresh TableView after Thread executions

In my application, I load a table with data.
In this tab, one column come from a webservice which can make some times to answer.
So I treat this one in pool thread to avoid to block the screen like this:
final ObservableList<StockListBean> list = FXCollections
.observableArrayList();
list.addAll(stocksListMService.getStocksListRunning());
stocksList.setItems(list);
final ExecutorService executor = Executors.newFixedThreadPool(4);
for (final StockListBean stockListBean : list) {
executor.execute(new Task<Float>() {
#Override
protected Float call() throws Exception {
logger.debug("In jfx task for {}", stockListBean.getCode());
((StockListRunningBean)stockListBean).setActualPrice(stocksListMService.getActualPrice(stockListBean.getCode()));
columnActualPrice.setVisible(false);
columnActualPrice.setVisible(true);
return 0f;
}
});
}
Threads are well execute and data are well set in beans but I don't reach to refresh the tableView.
I try code in the snapshot. I try many other ways found on the web but nothing to do, the column is desperately empty.
If I keep the thread loop but without execute the service and set a default value, the column is not empty.
It's such a real problem with screen refresh.
How can I refresh this ?
Thanks.
Assuming your StockListRunningBean uses JavaFX observable properties, so that the TableView sees the changes, you shouldn't need to do anything additional to update the table. One problem with your code is that you're making changes to the UI (via changes to the StockListRunningBean price property) from a thread that's not the FX Application Thread.
Try this refactoring:
for (final StockListBean stockListBean : list) {
final int code = stockListBean.getCode(); // assuming int, change as required
final Task<Float> task = new Task<Float>() {
#Override
protected Float call() throws Exception {
logger.debug("In jfx task for {}", code);
return stocksListMService.getActualPrice(code);
}
};
task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
#Override
public void handle(WorkerStateEvent event) {
((StockListRunningBean)stockListBean).setActualPrice(task.getValue());
}
});
executor.execute(task);
}
Again, this assumes that your StockListRunnerBean has a
public FloatProperty actualPriceProperty() {...}
method and that the table column is properly bound to it.

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);

Waiting for an unknown number of asynchronous tasks

I have a queue of tasks, and a thread that peek the queue once in a few seconds and if there is a task it performs it.
I have another code section (in another thread of course), that creates tasks in a loop (I can't know the number of tasks in advance from outside the loop) and insert them to the queue. The tasks contains some 'result' object, and the external thread (which created those tasks) need to wait for all the tasks to finish and finally get the result from each one of them.
The problem is that I can't pass java Semaphore\CountDownLatch etc to the result object since I don't know the number of monitors in advance.
I also can't use an Executor that uses invokeAll or wait for the Future object since the tasks are unsynchrnized (the external thread just pust the task to a queue and another thread will execute the task when he have time for this).
The only solution I've had in mind is to create some 'Inverted Semaphore' class that holds a set of results and a monitors counter. The getResult function will check if the counter == 0 and if the answer is yes will notify some lock object, and the getResult function will wait for this lock:
public class InvertedSemaphore<T> {
Set<T> resultSet;
int usages;
final Object c;
public InvertedSemaphore() {
resultSet = Collections.synchronizedSet(new HashSet<T>());
usages = 0;
c = new Object();
}
public void addResult(T result) {
resultSet.add(result);
}
public void addResults(Set<T> result) {
resultSet.addAll(result);
}
public void acquire() {
usages++;
}
public void release() {
synchronized (c) {
if (--usages == 0) {
c.notify();
}
}
}
public Set<T> getResults() {
synchronized (c) {
try {
while (usages > 0) {
c.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return resultSet;
}
}
Each addTask method will invoke semaphore.acquire, and each of the (unsynchronized) tasks will invoke semaphore.release in the end of the task.
It sounds pretty complicated and I'm pretty sure there is a better solution for this in java concurrent library or something.
Any idea will be appriciated:)
If the tasks don't need to be processed in order, use an ExecutorCompletionService
More generally, it is not necessary to use invokeAll on an ExecutorService in order to get a Future for the result. ExecutorService#submit could be used for this purpose, or optionally, the task being created could implement Future itself, thus allowing the creator of the task to ask for the result at a later point in time.
Some code:
class MyTask {
AtomicReference<?> result = new AtomicReference<?>();
void run() {
//do stuff here
result.set(/* the result of the calculation */);
}
boolean resultReady() {
return result.get()!=null;
}
? get() {
return result.get();
}
}
... elsewhere in code
void createTasks() {
Collection<MyTask> c = new ...;
while(indeterminable condition) {
MyTask task = new MyTask();
c.add(task);
mysteryQueue.add(task);
}
while(haven't received all results) {
MyTask task = c.get(...); //or iterate or whatever
? result = task.get();
if (result!=null) {
//do stuff, probably remove the task from the collection c would be smart
}
}
}
One idea would be to use a separate queue for the results.
So you will have one blocking queue that thread A places tasks for thread B thereby having a producer-consumer approach, and when each task is completed, the result could be placed in the second result queue inverting the consumer-producer roles since now thread A that originally created the tasks will consume the result from the second queue.
You can do the following:
each producer will hold its own queue. The producer will pass a means to report to this queue to the Task itself. When the task finishes running, it will queue its result to this queue. It is beast described by some code:
class Result{}
interface IResultCallback{
void resultReady(Result r); // this is an abstraction of the queue
}
class Producer implements IResultCallback{
// the producer needs to pass itself to the constructor of the task,
// the task will only see its "resultReady" facade and will be able to report to it.
// the producer can aggragte the results at it will and execute its own computation as
// as soon it is ready
Queue<Result> results; // = init queue
#Override
public void resultReady(Result r) {
results.add(r);
if(results.size() == 9){
operate();
}
results.clear();
}
public void operate(){
// bla bla
}
}
public class Task {
IResultCallback callback;
public Task(IResultCallback callback){
this.callback = callback;
}
public void execute(){
// bla bla
Result r = null; // init result;
callback.resultReady(r);
}
}

Categories

Resources