Java how to get a map value in future? - java

Here's pseudo code:
//-- Thread A
sender.send(requestId, request);
// Wait receiver to receive response for that requestId
return requestIdToResponseMap.get(requestId);
//--- Thread B
response = receiver.receive();
requestIdToResponseMap.put(response.requestId, response);
Note:
The call to downstream service is:
time consuming
asynchronized (i.e. response for request can only be mapped by request-id)
Let's say downstream service is a websocket client. The server sends messages and waits for responses.
About the requestIdToResponseMap, I tried 3 solutions:
Use a requestIdToLockMap to hold the locks, and use requestIdToResponseMap to hold the response values, but it seems complicated.
Use Map< String, Optional< Response>>, but Optional is immutable, I can not change its value. This doesn't work.
Use Map< String, Pair< Lock, Response>>, the receiver notifies the corresponding lock, then sender thread gets notified and retrieves the value.
So, for this kind of problem, what's the usual solution?

You didn't go into detail on your use case, so I'll answer the question generally:
Java has an entire framework for multi-threaded consumer-producer cases. If you find yourself thinking about locks and thread primitives, you're probably reinventing the wheel. Focus on the important stuff :-)
Here's a snippet to get you started:
// create your thread pool, threads here will consume your "requests"
ExecutorService threadPool = Executors.newFixedThreadPool(1);
// submit a request to the pool. This gets enqueued on a queue, until it is picked up by a thread. Returns a future- a reference to the uncompleted work
Future<Response> future = threadPool.submit(new RequestTask<Response>(request, requestId));
// wait for the work to complete
Response response = future.get();
your RequestTask implements Callable:
private static class RequestTask implements Callable<Response> {
#Override
public Response call() throws Exception {
...
}
}
Just to be clear, your producer thread is the "main" thread (A in your example) and the consumer is in the thread pool (thread B). You can increase your thread pool size (to a certain extent) to increase your request throughput.
There's tons of references about Java's ExecutorService and producer-consumer pattern. Remember that you have a queue in between producer and consumer threads, since you may produce requests faster than you can consume. It's unbounded by default, very important to remember that!
Let us know if you have any more questions.

Create map which will store reponsefuture which will be blocking if result is not available thread will wait .You can modify with other functionality like wait for how much time.
private static ConcurrentHashMap<String, ExecutorSeriveInstanceFuture> instanceMap = new ConcurrentHashMap<String, ExecutorSeriveInstanceFuture>();
customize Future so you can modify according to your use case.
private static class ExecutorSeriveInstanceFuture {
private DBExecutorSerive dbExecutorSerive;
private Throwable throwable;
private Object lock = new Object();
public DBExecutorSerive get() {
if (dbExecutorSerive == null) {
return dbExecutorSerive;
}
boolean restoreInterrupt = false;
synchronized (lock) {
while (dbExecutorSerive == null && throwable == null) {
try {
lock.wait();
} catch (InterruptedException e) {
restoreInterrupt = true;
}
}
}
if (restoreInterrupt) {
Thread.currentThread().interrupt();
}
if (dbExecutorSerive != null) {
return dbExecutorSerive;
}
throw new IllegalStateException(throwable);
}
public void set(DBExecutorSerive dbExecutorSerive) {
synchronized (lock) {
this.dbExecutorSerive = dbExecutorSerive;
lock.notifyAll();
}
}
public void setFailure(Throwable throwable) {
synchronized (lock) {
this.throwable = throwable;
lock.notifyAll();
}
}
}

Related

Locking only on a single entry point

I am utilizing an ExcutorService to submit tasks to run in parallel. The order of the tasks does not matter. However, the service may change, specifically when the requested size of the pool needs to change.
public class Service {
private volatile ExecutorService service = Executors.newFixedThreadPool(4);
private final ReentrantLock serviceLock = new ReentrantLock();
public Future<Object> postRequest(final Callable<Object> request) {
try {
serviceLock.lock(); // ?
return service.submit(request);
} finally {
serviceLock.unlock(); // ?
}
}
public void setSize(final int size) {
try {
if (size <= 0) {
throw new IllegalArgumentException("service pool size must positive");
}
serviceLock.lock();
service = Executors.newFixedThreadPool(size);
} finally {
serviceLock.unlock();
}
}
}
Obviously, I don't think I need the locking and unlocking in the postRequest method when it is the only method being called.
I only need to lock on postRequest during access to setSize. Otherwise, the extra time required to lock and unlock is just pointless. I believe this is necessary, seeing as the size will rarely change (maybe once or twice) compared to hundreds of requests being submitted.
Is there a way to avoid the locking on postRequest when it is not needed (when setSize is not being accessed)?
Since the Executor is in fact a ThreadPoolExecutor you can apply a cast and use its setMaximumPoolSize method.
You may add a type check in the setSize method in case of a future update of the JVM spec.
if (e instanceof ThreadPoolExecutor) {
((ThreadPoolExecutor) e).setMaximumPoolSize(size);
}
See https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html#setMaximumPoolSize(int)
#Obicere, you are right, you dont need to lock on postRequest which will have performance overhead.
Use something like this inside postRequest
public Future<Object> postRequest(final Callable<Object> request) {
try {
while(serviceLock.isLocked()) { // i.e acquired by setSize method
Thread.currentThread().sleep(/*some very small time */);
}
return service.submit(request);
} finally {
}
}
Also, please consider using ThreadPoolExecutor instead of FixedPoolThread because in your case, it was never a fixed pool thread :)
You can create a thread pool executor explicitly and then use setMaximumPoolSize():
private final ThreadPoolExecutor service = new ThreadPoolExecutor(4,4,0, TimeUnit.MINUTE, new LinkedBlockingQueue());
public void setSize(final int size) {
service.setMaximumPoolSize(size);
}

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

Producer-consumer inter-thread communication

having trouble with inter-thread communication and "solved" it by using "dummy messages" all over the place. Is this a bad idea? What are possible solutions?
Example Problem i have.
main thread starts a thread for processing and inserting records into database.
main thread reads a possibly huge file and puts one record (object) after another into a blockingqueue. processing thread reads from queue and does work.
How do I tell "processing thread" to stop?
Queue can be empty but work is not done and the main thread does not now either when processing thread has finished work and can't interrupt it.
So processing thread does
while (queue.size() > 0 || !Thread.currentThread().isInterrupted()) {
MyObject object= queue.poll(100, TimeUnit.MILLISECONDS);
if (object != null) {
String data = object.getData();
if (data.equals("END")) {
break;
}
// do work
}
}
// clean-up
synchronized queue) {
queue.notifyAll();
}
return;
and main thread
// ...start processing thread...
while(reader.hasNext(){
// ...read whole file and put data in queue...
}
MyObject dummy = new MyObject();
dummy.setData("END");
queue.put(dummy);
//Note: empty queue here means work is done
while (queue.size() > 0) {
synchronized (queue) {
queue.wait(500); // over-cautios locking prevention i guess
}
}
Note that insertion must be in same transaction and transaction can't be handled
by main thread.
What would be a better way of doing this?
(I'm learning and don't want to start "doing it the wrong way")
These dummy message is valid. It is called "poison". Something that the producer sends to the consumer to make it stop.
Other possibility is to call Thread.interrupt() somewhere in the main thread and catch and handle the InterruptedException accordingly, in the worker thread.
"solved" it by using "dummy messages" all over the place. Is this a
bad idea? What are possible solutions?
It's not a bad idea, it's called "Poison Pills" and is a reasonable way to stop a thread-based service.
But it only works when the number of producers and consumers is known.
In code you posted, there are two threads, one is "main thread", which produces data, the other is "processing thread", which consumes data, the "Poison Pills" works well for this circumstance.
But to imagine, if you also have other producers, how does consumer know when to stop (only when all producers send "Poison Pills"), you need to know exactly the number of all the producers, and to check the number of "Poison Pills" in consumer, if it equals to the number of producers, which means all producers stopped working, then consumer stops.
In "main thread", you need to catch the InterruptedException, since if not, "main thread" might not able to set the "Poison Pill". You can do it like below,
...
try {
// do normal processing
} catch (InterruptedException e) { /* fall through */ }
finally {
MyObject dummy = new MyObject();
dummy.setData("END");
...
}
...
Also, you can try to use the ExecutorService to solve all your problem.
(It works when you just need to do some works and then stop when all are finished)
void doWorks(Set<String> works, long timeout, TimeUnit unit)
throws InterruptedException {
ExecutorService exec = Executors.newCachedThreadPool();
try {
for (final String work : works)
exec.execute(new Runnable() {
public void run() {
...
}
});
} finally {
exec.shutdown();
exec.awaitTermination(timeout, unit);
}
}
I'm learning and don't want to start "doing it the wrong way"
You might need to read the Book: Java Concurrency in Practice. Trust me, it's the best.
What you could do (which I did in a recent project) is to wrap the queue and then add a 'isOpen()'method.
class ClosableQ<T> {
boolean isOpen = true;
private LinkedBlockingQueue<T> lbq = new LinkedBlockingQueue<T>();
public void put(T someObject) {
if (isOpen) {
lbq.put(someObject);
}
}
public T get() {
if (isOpen) {
return lbq.get(0);
}
}
public boolean isOpen() {
return isOpen;
}
public void open() {
isOpen = true;
}
public void close() {
isOpen = false;
}
}
So your writer thread becomes something like :
while (reader.hasNext() ) {
// read the file and put it into the queue
dataQ.put(someObject);
}
// now we're done
dataQ.close();
and the reader thread:
while (dataQ.isOpen) {
someObject = dataQ.get();
}
You could of course extend the list instead but that gives the user a level of access you might not want. And you need to add some concurrency thingies to this code, like AtomicBoolean.

Wait until any of Future<T> is done

I have few asynchronous tasks running and I need to wait until at least one of them is finished (in the future probably I'll need to wait util M out of N tasks are finished).
Currently they are presented as Future, so I need something like
/**
* Blocks current thread until one of specified futures is done and returns it.
*/
public static <T> Future<T> waitForAny(Collection<Future<T>> futures)
throws AllFuturesFailedException
Is there anything like this? Or anything similar, not necessary for Future. Currently I loop through collection of futures, check if one is finished, then sleep for some time and check again. This looks like not the best solution, because if I sleep for long period then unwanted delay is added, if I sleep for short period then it can affect performance.
I could try using
new CountDownLatch(1)
and decrease countdown when task is complete and do
countdown.await()
, but I found it possible only if I control Future creation. It is possible, but requires system redesign, because currently logic of tasks creation (sending Callable to ExecutorService) is separated from decision to wait for which Future. I could also override
<T> RunnableFuture<T> AbstractExecutorService.newTaskFor(Callable<T> callable)
and create custom implementation of RunnableFuture with ability to attach listener to be notified when task is finished, then attach such listener to needed tasks and use CountDownLatch, but that means I have to override newTaskFor for every ExecutorService I use - and potentially there will be implementation which do not extend AbstractExecutorService. I could also try wrapping given ExecutorService for same purpose, but then I have to decorate all methods producing Futures.
All these solutions may work but seem very unnatural. It looks like I'm missing something simple, like
WaitHandle.WaitAny(WaitHandle[] waitHandles)
in c#. Are there any well known solutions for such kind of problem?
UPDATE:
Originally I did not have access to Future creation at all, so there were no elegant solution. After redesigning system I got access to Future creation and was able to add countDownLatch.countdown() to execution process, then I can countDownLatch.await() and everything works fine.
Thanks for other answers, I did not know about ExecutorCompletionService and it indeed can be helpful in similar tasks, but in this particular case it could not be used because some Futures are created without any executor - actual task is sent to another server via network, completes remotely and completion notification is received.
simple, check out ExecutorCompletionService.
ExecutorService.invokeAny
Why not just create a results queue and wait on the queue? Or more simply, use a CompletionService since that's what it is: an ExecutorService + result queue.
This is actually pretty easy with wait() and notifyAll().
First, define a lock object. (You can use any class for this, but I like to be explicit):
package com.javadude.sample;
public class Lock {}
Next, define your worker thread. He must notify that lock object when he's finished with his processing. Note that the notify must be in a synchronized block locking on the lock object.
package com.javadude.sample;
public class Worker extends Thread {
private Lock lock_;
private long timeToSleep_;
private String name_;
public Worker(Lock lock, String name, long timeToSleep) {
lock_ = lock;
timeToSleep_ = timeToSleep;
name_ = name;
}
#Override
public void run() {
// do real work -- using a sleep here to simulate work
try {
sleep(timeToSleep_);
} catch (InterruptedException e) {
interrupt();
}
System.out.println(name_ + " is done... notifying");
// notify whoever is waiting, in this case, the client
synchronized (lock_) {
lock_.notify();
}
}
}
Finally, you can write your client:
package com.javadude.sample;
public class Client {
public static void main(String[] args) {
Lock lock = new Lock();
Worker worker1 = new Worker(lock, "worker1", 15000);
Worker worker2 = new Worker(lock, "worker2", 10000);
Worker worker3 = new Worker(lock, "worker3", 5000);
Worker worker4 = new Worker(lock, "worker4", 20000);
boolean started = false;
int numNotifies = 0;
while (true) {
synchronized (lock) {
try {
if (!started) {
// need to do the start here so we grab the lock, just
// in case one of the threads is fast -- if we had done the
// starts outside the synchronized block, a fast thread could
// get to its notification *before* the client is waiting for it
worker1.start();
worker2.start();
worker3.start();
worker4.start();
started = true;
}
lock.wait();
} catch (InterruptedException e) {
break;
}
numNotifies++;
if (numNotifies == 4) {
break;
}
System.out.println("Notified!");
}
}
System.out.println("Everyone has notified me... I'm done");
}
}
As far as I know, Java has no analogous structure to the WaitHandle.WaitAny method.
It seems to me that this could be achieved through a "WaitableFuture" decorator:
public WaitableFuture<T>
extends Future<T>
{
private CountDownLatch countDownLatch;
WaitableFuture(CountDownLatch countDownLatch)
{
super();
this.countDownLatch = countDownLatch;
}
void doTask()
{
super.doTask();
this.countDownLatch.countDown();
}
}
Though this would only work if it can be inserted before the execution code, since otherwise the execution code would not have the new doTask() method. But I really see no way of doing this without polling if you cannot somehow gain control of the Future object before execution.
Or if the future always runs in its own thread, and you can somehow get that thread. Then you could spawn a new thread to join each other thread, then handle the waiting mechanism after the join returns... This would be really ugly and would induce a lot of overhead though. And if some Future objects don't finish, you could have a lot of blocked threads depending on dead threads. If you're not careful, this could leak memory and system resources.
/**
* Extremely ugly way of implementing WaitHandle.WaitAny for Thread.Join().
*/
public static joinAny(Collection<Thread> threads, int numberToWaitFor)
{
CountDownLatch countDownLatch = new CountDownLatch(numberToWaitFor);
foreach(Thread thread in threads)
{
(new Thread(new JoinThreadHelper(thread, countDownLatch))).start();
}
countDownLatch.await();
}
class JoinThreadHelper
implements Runnable
{
Thread thread;
CountDownLatch countDownLatch;
JoinThreadHelper(Thread thread, CountDownLatch countDownLatch)
{
this.thread = thread;
this.countDownLatch = countDownLatch;
}
void run()
{
this.thread.join();
this.countDownLatch.countDown();
}
}
If you can use CompletableFutures instead then there is CompletableFuture.anyOf that does what you want, just call join on the result:
CompletableFuture.anyOf(futures).join()
You can use CompletableFutures with executors by calling the CompletableFuture.supplyAsync or runAsync methods.
Since you don't care which one finishes, why not just have a single WaitHandle for all threads and wait on that? Whichever one finishes first can set the handle.
See this option:
public class WaitForAnyRedux {
private static final int POOL_SIZE = 10;
public static <T> T waitForAny(Collection<T> collection) throws InterruptedException, ExecutionException {
List<Callable<T>> callables = new ArrayList<Callable<T>>();
for (final T t : collection) {
Callable<T> callable = Executors.callable(new Thread() {
#Override
public void run() {
synchronized (t) {
try {
t.wait();
} catch (InterruptedException e) {
}
}
}
}, t);
callables.add(callable);
}
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(POOL_SIZE);
ExecutorService executorService = new ThreadPoolExecutor(POOL_SIZE, POOL_SIZE, 0, TimeUnit.SECONDS, queue);
return executorService.invokeAny(callables);
}
static public void main(String[] args) throws InterruptedException, ExecutionException {
final List<Integer> integers = new ArrayList<Integer>();
for (int i = 0; i < POOL_SIZE; i++) {
integers.add(i);
}
(new Thread() {
public void run() {
Integer notified = null;
try {
notified = waitForAny(integers);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("notified=" + notified);
}
}).start();
synchronized (integers) {
integers.wait(3000);
}
Integer randomInt = integers.get((new Random()).nextInt(POOL_SIZE));
System.out.println("Waking up " + randomInt);
synchronized (randomInt) {
randomInt.notify();
}
}
}

Categories

Resources