Does invokeAll() stop the main Thread? - concurrency

I'm wondering if the main thread waits until all tasks in invokeAll() parameter finish before it continues. Here's my code and it seems that it does.
public static void main(String[] args) throws InterruptedException {
ExecutorService service = null;
try
{
service = Executors.newCachedThreadPool();
List<Callable<?>> list = new ArrayList<>();
for(int i = 0; i < 1000; i++)
{
list.add(() -> {System.out.println("Not yet"); return null;});
}
service.invokeAll(list);
System.out.println("END!"); // Output "END" at last no matter what
}
finally
{
if(service != null)
{
service.shutdown();
}
}
}
As you can see, no matter how many tasks I created, whether it is 1000 or 10000, the program still outputs "END" at last.
Can anyone confirms this information? Thank you so much!

This is what the javadoc for invokeAll(...) says (my commentary inserted):
Executes the given tasks, returning a list of Futures holding their status and results when all complete.
Note: "when all complete" ... not before.
Future.isDone() is true for each element of the returned list.
This means that the tasks have completed.
Note that a completed task could have terminated either normally or by throwing an exception. The results of this method are undefined if the given collection is modified while this operation is in progress.
Parameters: tasks - the collection of tasks
Returns: A list of Futures representing the tasks, in the same sequential order as produced by the iterator for the given task list, each of which has completed.
Once again ... it says that the tasks have completed.
In short, it says three times that the tasks have completed before invokeAll() returns.

The ExecutorService.invokeAll() documentation states (emphasis is mine) :
Executes the given tasks, returning a list of Futures holding their
status and results when all complete.
And the ExecutorService class documentation underlines this point for every method designed to run tasks (emphasis is mine) :
Methods invokeAny and invokeAll perform the most commonly useful forms
of bulk execution, executing a collection of tasks and then waiting
for at least one, or all, to complete.
At least one being for invokeAny() and all for invokeAll().

Related

Create threads dynamically depending on time needs of single tasks

Say I have a list of callable objects like
std::list<std::shared_ptr<Callable>> tasks;
and the task is to run them all in an infinite loop, say
void run_all(const bool& abort){
while(true){
for(const auto& ptr : tasks){
if (abort) return;
(*ptr)();
}
}
}
This is fine as long as every "task" finishes after short time. Now I'd like to add the requirement that whenever a task needs more time than a specific threshold, a new thread should be created so that the other tasks do not have do wait for a specific long running task.
The simplest solution regarding code complexity I can think of at the moment would be creating a thread for each task:
void run_all(const bool& abort){
auto job = [&](std::shared_ptr<Callable> task){
while (!abort){
(*task)();
}
};
std::list<std::thread> threads;
for(auto& ptr : tasks){
threads.emplace_back(job, ptr);
}
for(auto& t : threads){
t.join();
}
}
But this might create inappropriate many threads.
What is an appropriate way to implement running the tasks and create threads dynamically depending on how long a tasks needs to be finished? Say we have got some
std::chrono::duration threshold;
and the goal is to run the first task and continue with the next afterwards if the first one takes no longer than threshold until finish, but create a new thread to run the rest of the tasks in parallel, if the first task does not finish before threashold. The generalized goal is:
If there is no task that has been finished in some thread so that another task began to run during the certain period of time threshold, then a new thread should be created so that other tasks which may potentially run in very short time do not have to wait.
If there are more than 3 threads that finish at least one task per period threshold, one of them should be joined.
There may be tasks that itself run ad infinitum. This should have no effect on the other tasks.
What could be an appropriate implementation satisfying these requirements or at least doing something related or at least a concept of an implementation?
Or is it completely fine to just create a bunch of threads? (I think about running such an application on a low performance machine like Raspberry Pi and a set of 50 to 300 tasks that should be treated.)

Implementing a custom async task type and await

I am developing a C++ app in which i need to receive messages from an MQ and then parsing them according to their type and for a particular reason I want to make this process (receiving a single message followed by processing it) asynchronous. Since, I want to keep things as simple as possible in a way that the next developer would have no problem continuing the code, I have written a very small class to implement Asynchrony.
I first raise a new thread and pass a function to the thread:
task = new thread([&] {
result = fn();
isCompleted = true;
});
task->detach();
and in order to await the task I do the following:
while (!isCompleted && !(*cancelationToken))
{
Sleep(5);
}
state = 1; // marking the task as completed
So far there is no problem and I have not faced any bug or error but I am not sure if this is "a good way to do this" and my question is focused on determining this.
Read about std::future and std::async.
If your task runs in another core or processor, the variable isCompleted may become un-synchronized having two copies in core cache. So you may be waiting more than needed.
If you have to wait for something it is better to use a semaphore.
As said in comments, using standard methods is better anyway.

Play Framework 2.4 Sequential run of multiple Promises

I have got a Play 2.4 (Java-based) application with some background Akka tasks implemented as functions returning Promise.
Task1 downloads bank statements via bank Rest API.
Task2 processes the statements and pairs them with customers.
Task3 does some other processing.
Task2 cannot run before Task1 finishes its work. Task3 cannot run before Task2. I was trying to run them through sequence of Promise.map() like this:
protected F.Promise run() throws WebServiceException {
return bankAPI.downloadBankStatements().map(
result -> bankProc.processBankStatements().map(
_result -> accounting.checkCustomersBalance()));
}
I was under an impression, that first map will wait until Task1 is done and then it will call Task2 and so on. When I look into application (tasks are writing some debug info into log) I can see, that tasks are running in parallel.
I was also trying to use Promise.flatMap() and Promise.sequence() with no luck. Tasks are always running in parallel.
I know that Play is non-blocking application in nature, but in this situation I really need to do things in right order.
Is there any general practice on how to run multiple Promises in selected order?
You're nesting the second call to map, which means what's happening here is
processBankStatements
checkCustomerBalance
downloadBankStatements
Instead, you need to chain them:
protected F.Promise run() throws WebServiceException {
return bankAPI.downloadBankStatements()
.map(statements -> bankProc.processBankStatements())
.map(processedStatements -> accounting.checkCustomersBalance());
}
I notice you're not using result or _result (which I've renamed for clarity) - is that intentional?
Allright, I found a solution. The correct answer is:
If you are chaining multiple Promises in the way I do. That means, in return of map() function you are expecting another Promise.map() function and so on, you should follow these rules:
If you are returning non-futures from mapping, just use map()
If you are returning more futures from mapping, you should use flatMap()
The correct code snippet for my case is then:
return bankAPI.downloadBankStatements().flatMap(result -> {
return bankProc.processBankStatements().flatMap(_result -> {
return accounting.checkCustomersBalance().map(__result -> {
return null;
});
});
});
This solution was suggested to me a long time ago, but it was not working at first. The problem was, that I had a hidden Promise.map() inside function downloadBankStatements() so the chain of flatMaps was broken in this case.

create_task and return values

I need to call an Async method within a method I declared. The method should return a value. I'm trying to wrap calls to the Windows Store into an easy to use class. My method should look like this:
bool Purchase(enum_InAppOption optionToPurchase);
enum_InAppOption is an enum consisting of all In-App options to purchase. At some point I need to call RequestProductPurchaseAsync. The result of this call determines if the method should return trueor false. I'm new to c++/cx (or at least I have a long history between now and the last time I used c++), so maybe this is easier as I think.
The create_task looks like this:
create_task(CurrentAppSimulator::RequestProductPurchaseAsync(this->_LastProductId, false))
The options I considered / tried:
returning the task would not abstract the store
tried to call wait on the task. I've got the exception An invalid parameter was passed to a function that considers invalid parameters fatal.
tried to use structured_task_group but it seems this does not allow for non void returning methods or I'm trying to provide a wrong interpretation. Compiler returns error C2064 (have googled but I can't get the point what to change)
Using an array of tasks and when_all
Found the following code on http://msdn.microsoft.com/en-us/library/dd492427.aspx#when_all in the middle of the page:
array<task<void>, 3> tasks =
{
create_task([] { wcout << L"Hello from taskA." << endl; }),
create_task([] { wcout << L"Hello from taskB." << endl; }),
create_task([] { wcout << L"Hello from taskC." << endl; })
};
auto joinTask = when_all(begin(tasks), end(tasks));
// Print a message from the joining thread.
wcout << L"Hello from the joining thread." << endl;
// Wait for the tasks to finish.
joinTask.wait();
So I tried to translate it into the following code:
array<task<Platform::String^>,1> tasks = {
create_task(CurrentAppSimulator::RequestProductPurchaseAsync(this->_LastProductId, false))
};
Even though I included the compiler throws C2065 ('array': undeclared identifier), C2275 ('Concurrency::task<_ReturnType>': illegal use of this type as an expression and some errors that seem to be errors following up on those two.
To sum up: How to make the method return after the async task has completed, so I can return a meaningful result based on the stuff going on asynchronously?
How to make the method return after the async task has completed, so I can return a meaningful result based on the stuff going on asynchronously?
This doesn't make much sense: the "stuff" isn't asynchronous if you want to wait for it to complete before returning. That's the definition of synchronous.
When using C++/CX, you cannot wait on a not-yet-completed task on an STA. Any attempt to do so will result in an exception being thrown. If you are going to call Purchase() on an STA and if it starts an asynchronous operation, you cannot wait for that operation to complete before returning.
Instead, you can use .then to perform another operation when the asynchronous operation completes. If the continuation needs to be performed on the invoking thread, make sure to pass the use_current() continuation context to ensure that the continuation is executed in the correct context.
Sascha,
Returning a task would abstract out the store, and I think that would be the most reasonable decision, since you are not restricting the users of your helper class to get the results straight away, but also allowing them to handle the results in their own way and asynchronously.
As #James correctly mentioned, you are not allowed to wait in the UI thread, then you will make the app unresponsive, there are different ways to avoid waiting:
create a continuation with concurrency::task::then;
you cannot wait in the UI thread, but you can wait for an operation on the UI thread to complete, that means you can wrap the future result of the task running on UI in a task_completion_event and then wait on the event in another (background) thread and handle the result;
concurrency::task_completion_event<Platform::String^> purchaseCompleted;
create_task(CurrentAppSimulator::RequestProductPurchaseAsync(
this->_LastProductId, false)).then(
[purchaseCompleted](concurrency::task<Platform::String^> task)
{
try
{
purchaseCompleted.set(task.get());
}
catch(Platform::Exception^ exception)
{
purchaseCompleted.set_exception(exception);
}
});
// and somewhere on non-UI thread you can do
Platform::String^ purchaseResult = create_task(purchaseCompleted).get();
you can achieve the previous trick using more WinRT-specific facilities rather than Concurrency Runtime, more precisely, IAsyncOperation<T>::Completed and IAsyncOperation<T>::GetResults;
and
seem irrelevant here, since you have only 1 real task, which is make a purchase.

Compilation error with C++ Metro App Tutorial - task continuation

I am working through the "Tutorial: Create your first Metro style app using C++" on msdn (link). And shortly into "part 2" of it, I am running into an error. I'm running this on a Windows 8 VM Release Preview (May 31st) with the Visual Studio 2012 Release Candidate (the latest).
Where I'm at is in the code section after adding the 3 new metro pages, the ItemsPage, the SplitPage, and the new "DetailPage". Adding those went fine, but when I add the code directly below, in the section labeled "To modify the asynchronous code that initializes the data model" it creates two copies of the error below:
error C2893: Failed to specialize function template ''unknown-type' Concurrency::details::_VoidReturnTypeHelper(_Function,int,...)' c:\program files (x86)\microsoft visual studio 11.0\vc\include\ppltasks.h 404 1 SimpleBlogReader
Then I took out all the code from that section and started adding it a piece at a time to find out where the error "really" was, as I obviously hadn't modified that standard header file. It turns out it's in the task chain in the App::InitDataSource method:
SyndicationClient^ client = ref new SyndicationClient();
for(wstring url : urls)
{
// Create the async operation.
// feedOp is an IAsyncOperationWithProgress<SyndicationFeed^, RetrievalProgress>^
auto feedUri = ref new Uri(ref new String(url.c_str()));
auto feedOp = client->RetrieveFeedAsync(feedUri);
// Create the task object and pass it the async operation.
// SyndicationFeed^ is the type of the return value
// that the feedOp operation will eventually produce.
// Then, initialize a FeedData object with the feed info. Each
// operation is independent and does not have to happen on the
// UI thread. Therefore, we specify use_arbitrary.
create_task(feedOp).then([this] (SyndicationFeed^ feed) -> FeedData^
{
return GetFeedData(feed);
}, concurrency::task_continuation_context::use_arbitrary())
// Append the initialized FeedData object to the list
// that is the data source for the items collection.
// This has to happen on the UI thread. By default, a .then
// continuation runs in the same apartment thread that it was called on.
// Because the actions will be synchronized for us, we can append
// safely to the Vector without taking an explicit lock.
.then([fds] (FeedData^ fd)
{
fds->Append(fd);
// Write to VS output window in debug mode only. Requires <windows.h>.
OutputDebugString(fd->Title->Data());
OutputDebugString(L"\r\n");
})
// The last continuation serves as an error handler. The
// call to get() will surface any exceptions that were raised
// at any point in the task chain.
.then( [this] (concurrency::task<SyndicationFeed^> t)
{
try
{
t.get();
}
// SyndicationClient throws E_INVALIDARG
// if a URL contains illegal characters.
catch(Platform::InvalidArgumentException^ e)
{
// TODO handle error. For example purposes
// we just output error to console.
OutputDebugString(e->Message->Data());
}
}); //end task chain
I took out the lambdas one at a time (and put in the semicolon so it'd compile), and if I have the first two, it's fine, but the last one in the chain causes an error. But if I create_task just the last one, it compiles. Or if I do it with the first and third it compiles. Or with just the first two.
Is the problem the second lambda? Is the header library getting confused on the void return type? Or is it something else? Working on this theory, I modified the "final" handler declaration to this:
// The last continuation serves as an error handler. The
// call to get() will surface any exceptions that were raised
// at any point in the task chain.
.then( [this] (concurrency::task<void> t)
Now THIS compiles. But according to the doc at msdn (here), is this right? There's a section called "Value-Based Versus Task-Based Continuations" on that page that is copied below:
Given a task object whose return type is T, you can provide a value of
type T or task to its continuation tasks. A continuation that takes
type T is known as a value-based continuation. A value-based
continuation is scheduled for execution when the antecedent task
completes without error and is not canceled. A continuation that takes
type task as its parameter is known as a task-based continuation. A
task-based continuation is always scheduled for execution when the
antecedent task finishes, even when the antecedent task is canceled or
throws an exception. You can then call task::get to get the result of
the antecedent task. If the antecedent task was canceled, task::get
throws concurrency::task_canceled. If the antecedent task threw an
exception, task::get rethrows that exception. A task-based
continuation is not marked as canceled when its antecedent task is
canceled.
Is this saying that the final continuation for error-handling should be the type of the final .then continuation, or the type of the original create_task? If it's the final (as I did above with void), will this continuation actually handle all above errors, or only errors for the final .then call?
Is this the right way to "fix" their example? Or not?
I think the problem is that you need a return type from the second lambda that will be fed to the third one (see the matching FeedData for the return type of the first task and parameter type for the second). Since the second task does not return anything void seems the correct choice. As you want to use the third to capture errors, you will need to go with concurrency::task<void> (based on the quote).
Also, based on the quote, this final task will get called if antecedent (the second in this case) task failed and will report any errors that happened during its execution when t.get() is called. I'm not sure about the case when the first fails, but you can try what happens by throwing an arbirtary exception from the first task.