In the below code, my main task is not waiting for the sub task to complete its execution. I am new to Java Thread. So I could not able to fix it. I google it and found no luck. Please help me in fixing this thread issue.
Code:
class ExecutorServiceManager{
public static ExecutorService getExecutor() {
if (executorService == null) {
try {
lock.lock();
if (executorService == null) {
executorService = Executors.newFixedThreadPool(150);
}
} finally {
lock.unlock();
}
}
if(executorService instanceof ThreadPoolExecutor) {
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executorService;
int corePoolSize = threadPoolExecutor.getCorePoolSize();
int maximumPoolSize = threadPoolExecutor.getMaximumPoolSize();
Logger.info(ExecutorServiceManager.class, "ExecutorInfo: CorePoolSize:%s, MaxPoolSize:%s", corePoolSize, maximumPoolSize);
}
return executorService;
}}
class ServiceImpl{
ExecutorServiceManager executorServiceManager;
private void processConversion(String category, Map<String, String> couchDeltaMap, String processKey, String reqId) {
try {
ProgressVo progressVo = new ProgressVo();
CountDownLatch pgCntxtcountDownLatch = new CountDownLatch(1);
executorServiceManager.getExecutor().submit(new MainTask(category, processKey, pgCntxtcountDownLatch, executorServiceManager, progressVo));
Logger.info(ServiceImpl.class, "ExecutorInfo: CorePoolSize:%s, MaxPoolSize:%s", corePoolSize, maximumPoolSize);
pgCntxtcountDownLatch.await();
} catch(InterruptedException ie) {}
catch(Exception ex) {}
}}
class MainTask implements Runnable{
#Override
public void run() {
executorService = executorServiceManager.getExecutor();
executorService.submit(new SubTask(progressVo, couchDeltaMap, reqId, executorServiceManager));
//I want the below operation to be executed, if and only the subtask completed its execution.
//But the below logger is printing before the subtask completed its execution.
Logger.info(MainTask.class, "It got executed before the subtask completed its processing");
pgCntxtcountDownLatch.countDown();
}}
class SubTask implements Runnable{
#Override
public void run() {
executorService = executorServiceManager.getExecutor();
doSomeProcess;
//It stopped in the middle, and the Main task started executing the remaining operation
}}
To get your main task to wait for the sub task execution, you could use the Future returned by Executor.submit() this way:
class MainTask implements Runnable{
#Override
public void run() {
executorService = executorServiceManager.getExecutor();
Future subTask = executorService.submit(new SubTask(progressVo, couchDeltaMap, reqId, executorServiceManager));
try{
subTask.get(); //wait for completion of the subtask
} catch(Exception e){
//You probably want better exception catching, this is just an example
}
Logger.info(MainTask.class, "It got executed before the subtask completed its processing");
pgCntxtcountDownLatch.countDown();
}}
class MainTask implements Runnable{
#Override
public void run() {
executorService = manager.getExecutor();
List<Future<Runnable>> futures = new ArrayList<Future<Runnable>>();
while (!pageCntxts.isEmpty()) {
popped = pageCntxts.pop();
Future future = executorService.submit(new SubTask(progressVo, couchDeltaMap, reqId,manager));
futures.add(future);
if(pageCntxts.isEmpty())
loadPageCntxtWithNext25Records(progressVo);
processNum++;
}
Logger.debug(MainTask.class, "Internal Thread Running Starts with data size: "+futures.size());
for (Future<Runnable> future : futures) {
future.get();
}
Logger.debug(MainTask.class, "Internal Thread Running Ends");}}
Related
Suppose there are multiple threads trying to find a value, whichever thread finds it first should send the output to the main thread and all other threads should be terminated.
Example -
public class WorkerThread implements Runnable {
#Override
public void run() {
// some long task here, returns int value
}
}
public class Main {
public static void main(String[] args){
// initialize multiple worker threads here
// then get result from the thread that completes first
}
}
I looked into docs and found invokeAny ExecutorService but this will return the result of any thread that has been completed successfully and not necessarily the first one.
As #Andy Turner said, use a CompletionService:
public static class WorkerThread implements Callable<Integer> {
#Override
public Integer call() throws Exception {
int nextInt = new Random().nextInt(10000);
try {
System.out.println("I will cost " + nextInt + " ms to finish job.--" + Thread.currentThread().getName());
Thread.sleep(nextInt);
} catch (InterruptedException ite) {
System.out.println("I am interrupted.--" + Thread.currentThread().getName());
return -1;
}
System.out.println("I am finish.--" + Thread.currentThread().getName());
return nextInt;
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
int nums = 3;
ExecutorService executorService = Executors.newFixedThreadPool(nums);
CompletionService<Integer> completionService = new ExecutorCompletionService<>(executorService);
while (nums-- > 0) {
completionService.submit(new WorkerThread());
}
Integer firstValue = completionService.take().get();
System.out.println("FirstValue is " + firstValue);
executorService.shutdownNow();
}
And you can see in output, only one thread will complete the job (Because only call completionService#take once
), other threads will be interrupted and exit
:
I will cost 8943 ms to finish job.--pool-1-thread-1
I will cost 9020 ms to finish job.--pool-1-thread-2
I will cost 5025 ms to finish job.--pool-1-thread-3
I am finish.--pool-1-thread-3
FirstValue is 5025
I am interrupted.--pool-1-thread-1
I am interrupted.--pool-1-thread-2
You can also use CountDownLatch and ExecutorService for achieving this.
Create CountDownLatch object with count = 1.
CountDownLatch latch = new CountDownLatch(1);
Use ExecutorService pool to execute the threads and pass the latch in all the threads.
workerThreadPool.execute(new WorkerThread(latch));
Wait for any thread to complete it's operation.
latch.await();
In the finally block of the thread run, shutdown the latch.
latch.countDown();
As soon as any thread countDown's the latch, the threadpool will stop all the other threads and shutdown.
workerThreadPool.shutdownNow();
The complete example would be below.
import static java.lang.Thread.sleep;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class WorkerThread implements Runnable
{
CountDownLatch _latch;
public WorkerThread(CountDownLatch latch)
{
_latch = latch;
}
#Override
public void run()
{
try
{
// some long task here, returns int value
System.out.println("In thread1 " + this.toString());
sleep(5000);
}
catch (InterruptedException ex)
{
System.out.println("thread1 interupted");
}
finally
{
System.out.println("Finished1 " + this.toString());
_latch.countDown();
}
}
}
class WorkerThread2 implements Runnable
{
CountDownLatch _latch;
public WorkerThread2(CountDownLatch latch)
{
_latch = latch;
}
#Override
public void run()
{
try
{
// some long task here, returns int value
System.out.println("In thread2 " + this.toString());
sleep(10000);
}
catch (InterruptedException ex)
{
System.out.println("thread2 interupted");
}
finally
{
System.out.println("Finished2 " + this.toString());
_latch.countDown();
}
}
}
public class Main
{
public static void main(String[] args) throws InterruptedException
{
ExecutorService workerThreadPool = Executors.newFixedThreadPool(2);
CountDownLatch latch = new CountDownLatch(1);
workerThreadPool.execute(new WorkerThread(latch));
workerThreadPool.execute(new WorkerThread2(latch));
latch.await();
workerThreadPool.shutdownNow();
}
}
You -could- pass a reference to the Thread where the Thread can send its results. But you'd better follow advice in the other answers and use a better API for this :)
public static void main(//) {
ResultConsumer r = new ResultConsumer();
... create and start worker threads
}
public class WorkerThread implements Runnable {
public WorkerThread ( ResultConsumer r ) {
this.r=r
}
#Override
public void run() {
// some long task here, returns int value
r.sendResult(....)
}
}
Faced the fact that when the database is unavailable, the queue grows because tasks stop running. What is the best way to set some timeout for tasks executed in method run()? May be there is some good approach with using ExecutorService?
#Service
public class AsyncWriter implements Writer, Runnable {
private LinkedBlockingQueue<Entry> queue = new LinkedBlockingQueue<>();
private volatile boolean terminate = false;
private AtomicInteger completedCounter = new AtomicInteger();
#PostConstruct
private void runAsyncWriter() {
Thread async = new Thread(this);
async.setName("Writer Thread");
async.setPriority(2);
async.start();
}
#Override
public void run() {
while (!terminate) {
try {
Entry entry = queue.take();
dao.save(entry);
completedCounter.incrementAndGet();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void write(Entry entry) {
queue.add(entry);
}
}
Maybe you can try RxJava
https://www.baeldung.com/rx-java
And you can set your aync funtions
Timeout in RxJava
I am creating my own thread pool and future object which can execute callable interface parallel. Executor provides shutdown method to stop all worker threads from running. If i am creating a thread pool like below how should I implement the shutdown method to stop after all threads have finished execution?
My custom thread pool looks like this
class MyThreadPool implements java.util.concurrent.Executor
{
private final java.util.concurrent.BlockingQueue<Callable> queue;
public MyThreadPool(int numThreads) {
queue = new java.util.concurrent.LinkedBlockingQueue<>();
for (int i=0 ; i<numThreads ; i++) {
new Thread(new Runnable(){
#Override
public void run() {
while(true) {
queue.take().call();
}
}
}).start();
}
}
#Override
public <T> Future<T> submit(Callable<T> callable) {
FutureTask<T> future = new FutureTask(callable);
queue.put(future);
return future;
}
public void shutdown(){ }
}
I couldnt think of a way to keep list of thread and then check if they are idle or not?
You definitely should hold references to the threads you're creating. For instance, set up a field threads of type List<Thread> and add the threads to this list from within the constructor.
Afterwards, you could implement shutdown() with the help of Thread#join():
public void shutdown() {
for (Thread t : threads) {
try {
t.join();
} catch (InterruptedException e) { /* NOP */ }
}
}
Don't forget to replace while (true) with an appropriate condition (which you toggle in shutdown()) and consider using BlockingQueue#poll(long, TimeUnit) rather than take().
EDIT: Something like:
public class MyThreadPool implements Executor {
private List<Thread> threads = new ArrayList<>();
private BlockingDeque<Callable> tasks = new LinkedBlockingDeque<>();
private volatile boolean running = true;
public MyThreadPool(int numberOfThreads) {
for (int i = 0; i < numberOfThreads; i++) {
Thread t = new Thread(() -> {
while (running) {
try {
Callable c = tasks.poll(5L, TimeUnit.SECONDS);
if (c != null) {
c.call();
}
} catch (Exception e) { /* NOP */ }
}
});
t.start();
threads.add(t);
}
}
public void shutdown() {
running = false;
for (Thread t : threads) {
try {
t.join();
} catch (InterruptedException e) { /* NOP */ }
}
}
// ...
}
I have a situation where i need to check if a certain condition is met and it needs to be periodically executed a certain number of times to check for the condition before it declares the condition as not met and between each execution there needs to be a delay/sleep interval.
Code Structure:
class checkCondition<T> implements Callable<T>{
#Override
public T call() {
//Do Stuff and return result
return result;
}
public class TaskRunner<T> {
private final ExecutorService executor = Executors.newSingleThreadExecutor();
public Future<T> runTask(checkCondiiton task, int times, long sleep){
while(times > 0){
future = executor.submit(task);
Thread.sleep(sleep);
times--;
}
return future;
}
}
}
Is the above implementation correct? If not, please advice on what would be better approach. I am new to ExecutorService and Java Concurrency.
Try using Executors.newSingleThreadScheduledExecutor()
Example:
public class FixedScheduledExcutor
{
public static void main(String[] args) throws InterruptedException
{
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
CountDownLatch latch = new CountDownLatch(5);
executorService.scheduleAtFixedRate(new MyRunner(latch), 5, 5, TimeUnit.SECONDS);
latch.await();
System.out.println("Shutting down service...");
executorService.shutdown();
}
}
class MyRunner implements Runnable
{
CountDownLatch latch;
MyRunner(CountDownLatch latch)
{
this.latch = latch;
}
#Override
public void run()
{
System.out.println("Do something : " + latch.getCount());
latch.countDown();
}
}
I am new to the Threading, so if please give me an advice for my case.
I would like create a new thread to do something and I don't care this thread can do complete or not.
I intend to use ExecutorCompletionService to do my job but this class is not suitable for me. It must call take or poll to drain a queue to avoid memory leak. So, this means I must wait until the thread complete. I read this from this question
This is the current code
ExecutorService executor = Executors.newCachedThreadPool();
CompletionService<Entity> completion = new ExecutorCompletionService<>(executor);
DoSomeThingClass doSomething = getInstance();
completion.submit(doSomething);
executor.shutdown();
// Continue to do other job and I don't care whenever doSomeThing is complete.
// However when doSomeThing finish, I don't need to do anything to avoid memory leak
For that reason, please give me an approach for my case and some skeleton code for example.
Thank you so much
You can mark this thread as "Daemon". And when your main thread completed, your app will exit.
public static void main(String[] args)
{
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
} catch(InterruptedException e) {}
System.out.println("Thread 2 is finished");
}
});
t.setDaemon(true);
t.start();
System.out.println("Thread 1 is finished");
}
You can use Spring TaskExecutor, it is very useful to raise a thread to run a task.
import org.springframework.core.task.TaskExecutor;
public class TaskExecutorExample {
private class MessagePrinterTask implements Runnable {
private String message;
public MessagePrinterTask(String message) {
this.message = message;
}
public void run() {
System.out.println(message);
}
}
private TaskExecutor taskExecutor;
public TaskExecutorExample(TaskExecutor taskExecutor) {
this.taskExecutor = taskExecutor;
}
public void printMessages() {
for(int i = 0; i < 25; i++) {
taskExecutor.execute(new MessagePrinterTask("Message" + i));
}
}
}
You can check Spring Task Execution documentation here:
http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html
Along with you code your Future concept
Future ft=completion.submit(doSomething);
ft.get(timeOut, TimeUnit.MILLISECONDS);
here you can specify Time to execute Thread if it fail to get execute thread get kill(not 100% sure)means it try to interrupt the thread and try to kill
I can resolve my problem as the following code
public static void main(
String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(new Runnable() {
#Override
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
} finally {
System.out.println("Thread 2 is finished");
}
}
});
executor.shutdown();
System.out.println("Thread 1 is finished");
}