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.
Related
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.
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
}
}
I have some basic project that has like four calls to some external resource, that in current version runs synchronously. What I would like to achieve is to wrap that calls into HystrixObservableCommand and then call it asynchronously.
From what I have read, after calling .observe() at the HystrixObservableCommand object, the wrapped logic should be called immediately and asynchronously. However I am doing something wrong, because it works synchronously.
In the example code, the output is Void, because I'm not interested in output (for now). That is also why I did not assigned the Observable to any object, just called constructor.observe().
#Component
public class LoggerProducer {
private static final Logger LOGGER = Logger.getLogger(LoggerProducer.class);
#Autowired
SimpMessagingTemplate template;
private void push(Iterable<Message> messages, String topic) throws Exception {
template.convertAndSend("/messages/"+topic, messages);
}
public void splitAndPush(Iterable<Message> messages) {
Map<MessageTypeEnum, List<Message>> groupByMessageType = StreamSupport.stream(messages.spliterator(), true)
.collect(Collectors.groupingBy(Message::getType));
//should be async - it's not
new CommandPushToBrowser(groupByMessageType.get(MessageTypeEnum.INFO),
MessageTypeEnum.INFO.toString().toLowerCase()).observe();
new CommandPushToBrowser(groupByMessageType.get(MessageTypeEnum.WARN),
MessageTypeEnum.WARN.toString().toLowerCase()).observe();
new CommandPushToBrowser(groupByMessageType.get(MessageTypeEnum.ERROR),
MessageTypeEnum.ERROR.toString().toLowerCase()).observe();
}
class CommandPushToBrowser extends HystrixObservableCommand<Void> {
private Iterable<Message> messages;
private String messageTypeName;
public CommandPushToBrowser(Iterable<Message> messages, String messageTypeName) {
super(HystrixCommandGroupKey.Factory.asKey("Messages"));
this.messageTypeName = messageTypeName;
this.messages = messages;
}
#Override
protected Observable<Void> construct() {
return Observable.create(new Observable.OnSubscribe<Void>() {
#Override
public void call(Subscriber<? super Void> observer) {
try {
for (int i = 0 ; i < 50 ; i ++ ) {
LOGGER.info("Count: " + i + " messageType " + messageTypeName);
}
if (null != messages) {
push(messages, messageTypeName);
LOGGER.info("Message type: " + messageTypeName + " pushed: " + messages);
}
if (!observer.isUnsubscribed()) {
observer.onCompleted();
}
} catch (Exception e) {
e.printStackTrace();
observer.onError(e);
}
}
});
}
}
}
There are some pure "test" code fragments there, as I was trying to figure out the problem, just ignore the logic, main focus is to make it run async with .observe(). I do know that I may achieve that with standard HystrixCommand, but this is not the goal.
Hope someone helps :)
Regards,
Answer was found:
"Observables do not add concurrency automatically. If you are modeling
synchronous, blocking execution with an Observable, then they will
execute synchronously.
You can easily make it asynchronous by scheduling on a thread using
subscribeOn(Schedulers.io()). Here is a simply example for wrapping a
blocking call with an Observable:
https://speakerdeck.com/benjchristensen/applying-reactive-programming-with-rxjava-at-goto-chicago-2015?slide=33
However, if you are wrapping blocking calls, you should just stick
with using HystrixCommand as that’s what it’s built for and it
defaults to running everything in a separate thread. Using
HystrixCommand.observe() will give you the concurrent, async
composition you’re looking for.
HystrixObservableCommand is intended for wrapping around async,
non-blocking Observables that don’t need extra threads."
-- Ben Christensen - Netflix Edge Engineering
Source: https://groups.google.com/forum/#!topic/hystrixoss/g7ZLIudE8Rs
I know there are probably a couple ways to do this, just looking for the most efficient and concise way to go about it:
public Object giveMeNewObject() {
final Object result = null;
SomeApiClient.start(new Callback() { // starts an async process
#Override
public void onSuccess(Object somethingNew) {
result = somethingNew; //ERROR; can't set cause final
}
});
return result; //result is null, cause Async already finished
}
From your code - this is modified on fly so correct mistakes and all will work as you expect - caller will wait untill 3rd party finishes the processing and will get the result of that process:
public Object giveMeNewObject() {
CountDownLatch latch=new CountDownLatch(1);
Callback callback=new Callback() {
public sometype result=null;
#Override
public void onSuccess(Object somethingNew) {
result = somethingNew; //ERROR; can't set cause final
latch.countDown();
}
});
SomeApiClient.start(callback);
latch.await(sometimetowait);
return callback.result;
}
Read the documentation of AsyncTask. Your job should be done in doInBackground method and the result should be returned by that method. Later on you can use get(Timeout) method to retrieve that returned value. get will even block if the computation in doInBackground is not complete yet for given ammount of the time.
You can find tons of examples of how to use async task. One of them is in the API documentation (link above)
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();
}
}
}