Is ordered execution expected on the single thread - java

Since the service is single threaded, the monkey1 loop series will always get executed before monkey2, so we can expect monkey1 will always be greater than monkey2, can't we?
import java.util.concurrent.*;
public class MonkeyCounter {
private static AtomicInteger monkey1 = new AtomicInteger(0);
private static AtomicLong monkey2 = new AtomicLong(0);
public static void main(String[] args) {
ExecutorService service = null;
try {
service = Executors.newSingleThreadExecutor();
for(int i=0; i<100; i++)
service.submit(() -> monkey1.getAndIncrement());
for(int i=0; i<100; i++)
service.submit(() -> monkey2.incrementAndGet());
System.out.println(monkey1+" "+monkey2);
} finally {
if(service != null) service.shutdown();
}
}
}

Javadoc on Executors.newSingleThreadExecutor:
Creates an Executor that uses a single worker thread operating off an unbounded queue. (Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.) Tasks are guaranteed to execute sequentially, and no more than one task will be active at any given time. Unlike the otherwise equivalent newFixedThreadPool(1) the returned executor is guaranteed not to be reconfigurable to use additional threads.
Tasks are placed in a queue. Queue are FIFO so with single thread, the monkey1 > monkey2 is guaranteed if none of the increment fails.
Bear in mind that value of monkey1 and monkey2 are undetermined because you do not wait for the jobs completion.

After Holger corrected me, with Executors.newSingleThreadExecutor()
tasks are guaranteed to execute sequentially.
In following example even if the first batch of tasks being submitted are blocking for 5 secs,
are completed first than the second batch of tasks with no blocking other than println.
example,
import java.util.concurrent.*;
public class ExecutorServiceTests {
public static void main(String[] args) {
java.util.concurrent.ExecutorService service = Executors.newSingleThreadExecutor();
for (int i = 0; i < 5; i++) {
service.submit(() -> {
block(5000);
System.out.println("execution1");
});
}
for (int i = 0; i < 5; i++) {
service.submit(() -> {
System.out.println("execution2");
});
}
service.shutdown();
}
private static void block(int ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Output:
execution1
execution1
execution1
execution1
execution1
execution2
execution2
execution2
execution2
execution2

Related

Parallelize and monitor tasks with ExecutorService

I have a function/task void task() that needs to be called about 4-6 million times.
I want to parallelize this operation over threads in a thread pool.
I do not care about the return value of the tasks so I can avoid messing around with Future<T>.
I want to periodically poll the status of how the threads are coming along. The status is simply how many invocations of task() returned cleanly and how many threw an exception.
Here's what I came up with:
class Test {
AtomicInteger success = new AtomicInteger(0);
AtomicInteger failed = new AtomicInteger(0);
CountDownLatch latch = new CountDownLatch(1_000_000);
private void start() {
ExecutorService executorService = Executors.newFixedThreadPool();
for (int i = 0; i < 1_000_000; i++) {
executorService.execute(this::task);
}
while (!countDownLatch.await(1, TimeUnit.SECONDS)) {
log("Success: %d Failed: %d", success.get(), failed.get());
}
log("===================== Final tally =====================");
log("Success: %d Failed: %d", success.get(), failed.get());
executorService.shutdown();
}
private void task() {
try {
doSomeStuff();
success.incrementAndGet()
} catch(Exception e) {
failed.incrementAndGet();
}
countDownLatch.countDown();
}
}
Two AtomicInteger that the threads use to record successes or failures and a CountDownLatch that the "monitor" thread uses to check on the progress.
Is there a more idiomatic way to do this? Some thing that doesn't involve submitting millions of Runnable lambdas to the ExecutorService perhaps?
I could put the whole thing in an
IntStream.range(0, 1_000_000).parallelStream().map(...).groupBy(...)
but I won't be able to monitor the progress.
If you want to use stream as you proposed, you can move your monitoring part into another thread like this:
new Thread(()->{
while (!countDownLatch.await(1, TimeUnit.SECONDS)) {
log("Success: %d Failed: %d", success.get(), failed.get());
}
log("===================== Final tally =====================");
log("Success: %d Failed: %d", success.get(), failed.get());
}).start()
IntStream.range(0, 1_000_000).parallelStream().map(...).groupBy(...)

How to wait for main Thread until asynchronous methods will finish?

I have Service.class with start() method:
public void start() {
for (int i = 0; i < companiesList.size(); i++) {
asychronous.someAsynchronous(...);
}
log.info("Start method has finished");
}
I have Asynchronous.class with someAsynchronous() method:
#Async("threadPoolTaskExecutor")
public CompletableFuture<Void> someAsynchronous(some_parameters) {
//do some stuff
return null;
}
The log.info() shows up before someAsynchronous() methods has finished.
How to force it to wait for log.info() until someSynchronous() methods in loop will finish? Btw: Asynchronous threads are still running after finishing loop.
The CompletableFuture<Void> calls are requested to be executed but after all of them start in separate threads, the for-loop finishes and the log is printed even before any of them finished. This is the advantage of the asynchronous processing - you don't care about their results and how much time they took to execute.
To achieve you want, you have to periodically check whether all of them are finished before you proceed to the log outoput.
// Adds executions to the List
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (int i = 0; i < companiesList.size(); i++) {
futures.add(asychronous.someAsynchronous(...));
}
// Periodical check
Iterator<CompletableFuture<Void>> iterator = futures.iterator();
while (iterator.hasNext()) {
CompletableFuture<Void> future = iterator.next(); // get the next one
if (future.isDone()) { // if finished...
//... // ... do an action
iterator.remove(); // ... and remove from the Iterator
}
if (!iterator.hasNext()) { // if you reach the end
iterator = futures.iterator(); // ... repeat the remaining Futures
}
}
log.info("Start method has finished");
Note this method doesn't finish until all of the executions are done.
Edit: Thanks to #Kayaman who suggested using a single method dedicated for that replacing the whole Iterator logics. The futures must be an array:
// Adds executions to the List
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (int i = 0; i < companiesList.size(); i++) {
futures.add(asychronous.someAsynchronous(...));
}
// Join the completion of all the threads
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
log.info("Start method has finished");

Java parallel tasks , only executing once

This code I have is not executing tasks in parallel,
it only executes the code in this case once (whatever is in the for loop, but it should be 2) :
public class mqDirect {
public static void main(String args[]) throws Exception {
int parallelism = 2;
ExecutorService executorService =
Executors.newFixedThreadPool(parallelism);
Semaphore semaphore = new Semaphore(parallelism);
for (int i = 0; i < 1; i++) {
try {
semaphore.acquire();
// snip ... do stuff..
semaphore.release();
} catch (Throwable throwable) {
semaphore.release();
}
executorService.shutdownNow();
}
}
}
In Java the main way to make code work in parallel is to create a Thread with a new Runnable as a constructor parameter. You then need to start it.
There are many tutorials to help you get this to happen properly.
As your code stands you are merely creating an ExecutorService (and not using it), creating a Semaphore (which should be done in the thread but isn't), performing some process and then shutting down the Executor.
BTW: ShutDownNow is probably not what you want, you should just use ShutDown.
OK, So I found this good tutorial
http://programmingexamples.wikidot.com/threadpoolexecutor
And I have done something like
public class mqDirect {
int poolSize = 2;
int maxPoolSize = 2;
long keepAliveTime = 10;
ThreadPoolExecutor threadPool = null;
final ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(
5);
public mqDirect()
{
threadPool = new ThreadPoolExecutor(poolSize, maxPoolSize,
keepAliveTime, TimeUnit.SECONDS, queue);
}
public void runTask(Runnable task)
{
threadPool.execute(task);
System.out.println("Task count.." + queue.size());
}
public void shutDown()
{
threadPool.shutdown();
}
public static void main (String args[]) throws Exception
{
mqDirect mtpe = new mqDirect();
// start first one
mtpe.runTask(new Runnable()
{
public void run()
{
for (int i = 0; i < 2; i++)
{
try
{
System.out.println("First Task");
runMqTests();
Thread.sleep(1000);
} catch (InterruptedException ie)
{
}
}
}
});
// start second one
/*
* try{ Thread.sleep(500); }catch(InterruptedException
* ie){}
*/
mtpe.runTask(new Runnable()
{
public void run()
{
for (int i = 0; i < 2; i++)
{
try
{
System.out.println("Second Task");
runMqTests();
Thread.sleep(1000);
} catch (InterruptedException ie)
{
}
}
}
});
mtpe.shutDown();
// runMqTests();
}
And it works !
But the problem is , this duplicated code ... runMqtests() is the same task, is there a way to specify it to run in parallel without duplicating the code?
The example I based this off is assuming each task is different.
This code I have is not executing tasks in parallel, it only executes the code in this case once (whatever is in the for loop, but it should be 2) :
Just because you instantiate an ExecutorService instance doesn't mean that things magically run in parallel. You actually need to use that object aside from just shutting it down.
If you want the stuff in the loop to run in the threads in the service then you need to do something like:
int parallelism = 2;
ExecutorService executorService = Executors.newFixedThreadPool(parallelism);
for (int i = 0; i < parallelism; i++) {
executorService.submit(() -> {
// the code you want to be run by the threads in the exector-service
// ...
});
}
// once you have submitted all of the jobs, you can shut it down
executorService.shutdown();
// you might want to call executorService.awaitTermination(...) here
It is important to note that this will run your code in the service but there are no guarantees that it will be run "in parallel". This depends on your number of processors and the race conditions inherent with threads. For example, the first task might start up, run, and finish its code before the 2nd one starts. That's the nature of threaded programs which are by design asynchronous.
If, however, you have at least 2 cores, and the code that you submit to be run by the executor-service takes a long time to run then most likely they will be running at the same time at some point.
Lastly, as #OldCurmudgeon points out, you should call shutdown() on the service which allows current jobs already submitted to the service to run as opposed to shutdownNow() which cancels and queued jobs and also calls thread.interrupt() on any running jobs.
Hope this helps.

ExecutorService.invokeAll and shutdown

So I have some Callable tasks, sensitive to interruptions, which I submit to the ExecutorService using invokeAll. After 5 seconds from another method I call executorService.shutdownNow after which I call the awaitTermination, which returns true, so all seems good. The problem is the executor never terminates.
Due to logging I know that each one of my tasks finished.
nevertheless the invokeAll still blocks on f.get when i is equal to the number of threads of the executor:
The following code is obtained from AbstractExecutorService + some logging.
#Override
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException {
if (tasks == null) throw new NullPointerException();
ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
boolean done = false;
try {
List<Callable<T>> list = new ArrayList<Callable<T>>();
for (Callable<T> t : tasks) {
list.add(t);
RunnableFuture<T> f = newTaskFor(t);
futures.add(f);
execute(f);
}
for (int i = 0, size = futures.size(); i < size; i++) {
Future<T> f = futures.get(i);
if (!f.isDone()) {
log.info("Future %s is not done!. Task %s", i, list.get(i));
try {
log.info("Get from future %s", i);
// NEXT LINE BLOCKS FOR i= NUMBER OF THREADS
f.get();
log.info("Got result from future %s", i);
} catch (CancellationException ignore) {
} catch (ExecutionException ignore) {
}
}
}
log.info("Obtained all!");
done = true;
return futures;
} finally {
if (!done) for (int i = 0, size = futures.size(); i < size; i++)
futures.get(i).cancel(true);
}
}
Am I not suppose to use invokeAll with shutdown? I guess not, after all they are in the same class. Why does it get blocked, only when i= the number of threads of the executor?
Yes, you're not suppose to use invokeAll with shutdown. At least this is what I understand, correct me if I'm wrong.
The shutdownNow method:
public List<Runnable> shutdownNow() {
...
checkShutdownAccess();
advanceRunState(STOP);
interruptWorkers();
tasks = drainQueue();
...
}
The only thing is does is interrupt working threads and remove the rest of the runnables from the working queue, see drainQueue. ShutdownNow/Shutdown does not modify the futures in our invokeAll method
So what happens in my case is that for an Executor with N threads, I invoke 300 jobs, each of them take more than 1 minute, after 5 seconds I cancel (interrupt working threads), N threads are interrupted (0 to N-1). What happens with the rest of the futures? Nothing, the next call to f.get() (see corresponding line in the question) will block and you're stuck there. This explains why I'm always blocked on i = Number of threads.

How to start two process at the same time and then wait both completed?

I want to start two process at the same time and make sure complete them all before proceeding other steps. Can you help? I already tried Thread, it can't start two at the same time and wait until been done.
final CyclicBarrier gate = new CyclicBarrier(3);
Thread r2 = new Thread()
{
public void run()
{
try
{
int i = 0;
while (i < 3)
{
System.out.println("Goodbye, " + "cruel world!");
Thread.sleep(2000L);
i++;
gate.await();
}
}
catch (InterruptedException | BrokenBarrierException iex)
{
}
}
};
Thread r3 = new Thread()
{
public void run()
{
try
{
int i = 0;
while (i < 3)
{
System.out.println("Goodbye, " + "cruel world!");
Thread.sleep(2000L);
i++;
gate.await();
}
}
catch (InterruptedException | BrokenBarrierException iex)
{
}
}
};
r2.start();
r3.start();
gate.await();
System.out.println("Donew");
You can use Thread.join()to wait until your subprocesses/threads have finished.
You should not need CyclicBarrier.
Your problem is that you are repeatedly waiting for three parties, but only two threads are calling await() repeatedly. I would expect your code to immediately print, "Goodbye, cruel world!" twice, and "Done", then hang, because the loops are waiting for a third thread to invoke await() again, but the main thread has now terminated.
One solution is for your main thread to loop, invoking await() the same number of times that your task does. But that would be kind of ugly.
I'd suggest using the invokeAll() method of an ExecutorService. This will submit your tasks to the service at (approximately) the same time, then block until all tasks complete. If you want to try to improve the simultaneity of the task commencing, you could add a CyclicBarrier, but it looks like you are more concerned with when the tasks end, and invokeAll() will take care of that for you.
final class Sample
implements Callable<Void>
{
private static final int ITERATIONS = 3;
private static final long AVG_TIME_MS = 2000;
public static void main(String[] args)
throws InterruptedException
{
List<Sample> tasks = Arrays.asList(new Sample(), new Sample());
ExecutorService workers = Executors.newFixedThreadPool(tasks.size());
for (int i = 1; i <= ITERATIONS; ++i) {
/* invokeAll() blocks until all tasks complete. */
List<Future<Void>> results = workers.invokeAll(tasks);
for (Future<?> result : results) {
try {
result.get();
}
catch (ExecutionException ex) {
ex.getCause().printStackTrace();
return;
}
}
System.out.printf("Completed iteration %d.%n", i);
}
workers.shutdown();
System.out.println("Done");
}
#Override
public Void call()
throws InterruptedException
{
/* The average wait time will be AVG_TIME_MS milliseconds. */
ThreadLocalRandom random = ThreadLocalRandom.current();
long wait = (long) (-AVG_TIME_MS * Math.log(1 - random.nextDouble()));
System.out.printf("Goodbye, cruel world! (Waiting %d ms)%n", wait);
Thread.sleep(wait);
return null;
}
}
Notice how I spiced things up with a random wait time. Yet, invokeAll() waits until all of tasks in that iteration complete.
It's impossible for the single processor machines.
Even if you find lot of answers on threads its not gonna start two process at the same time
If you accept the Relative Simultanity that will be easy.

Categories