So I have a Thread wherein ScheduledThreadPoolExecutor is created with periodic Task, so I want to stop my ScheduledThreadPoolExecutor from Task when condition occurs.
After that from Thread wherein ScheduledThreadPoolExecutor is existed to make a notify to another Thread. Perhaps I did something wrong, I cannot to send notify from InnerThread to parent Thread Buyer. After that from Buyer sending another notify to MasterContainer.
How can I do this?
import java.util.Date;
import java.util.concurrent.*;
public class Buyer implements Runnable {
private CommonObj cmnObj;
public Buyer(CommonObj msg) {
this.cmnObj = cmnObj;
}
#Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name + " is starting");
ScheduledThreadPoolExecutor sch = (ScheduledThreadPoolExecutor)
Executors.newScheduledThreadPool(1);
sch.setRemoveOnCancelPolicy(true);
FutureRunnable periodicTask = new FutureRunnable() {
#Override
public void run() {
try {
System.out.println("\t periodicTask Execution Time: "
+ ScheduledExample.fmt.format(new Date()));
try {
Thread.sleep(2 * 1000);
synchronized (this) {
System.out.println("\t periodicTask need to close: "
+ ScheduledExample.fmt.format(new Date()));
this.getFuture().cancel(true);
System.out.println("\t periodicTask cancelled: "
+ ScheduledExample.fmt.format(new Date()));
this.notify();
return;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\t periodicTask End Time: "
+ ScheduledExample.fmt.format(new Date()));
} catch (Exception e) {
}
}
};
Future<?> periodicFuture = sch.scheduleAtFixedRate(periodicTask, 3, 3, TimeUnit.SECONDS);
periodicTask.setFuture(periodicFuture);
synchronized (sch) {
try {
System.out.println(name + " is before wait");
sch.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + " is before notify");
this.notify();
}
System.out.println(name + " is ended");
}
}
abstract class FutureRunnable implements Runnable {
private Future<?> future;
public Future<?> getFuture() {
return future;
}
public void setFuture(Future<?> future) {
this.future = future;
}
}
In your code, your inner task syncronized on periodicTask and outer syncronized on sch, this does not work.
If you want to syncronize inner and outer thread, you should syncronize on the same object, as well as call wait and notify on the same object.
Related
I have 3 threads in my application, but I am allowed to run only 2 threads in parallel.
once 1 either of the tread will stop, 3rd thread will start.
I know Thread, runnable start(), run() etc in Java, But I dont know how to implement above situation. your little guidance will be very helpful
Try using semaphore;
public class Main {
private static final Semaphore SEMAPHORE = new Semaphore(2);
public static void main(String[] args) {
runThread(new Thread(() -> runInThread(1)));
runThread(new Thread(() -> runInThread(2)));
runThread(new Thread(() -> runInThread(3)));
}
public static void runThread(Thread thread) {
try {
SEMAPHORE.acquire();
thread.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void runInThread(int i) {
System.out.println("Thread " + i + " is running");
System.out.println("Thread " + i + " is waiting");
try {
Thread.sleep(i * 2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread " + i + " is finish");
SEMAPHORE.release();
}
}
I have a need of a threadpool executor, which needs to complete an exact number (same) tasks.
It has to be able to re-submit failed tasks for an n number of times. If any of the tasks fail for more than n, then the threadpool should shutdown and not continue to process any other tasks.
I have tried to combine 2 approaches which I've found in different answers - one for re-submitting failed tasks by overriding ThreadPoolExecutor.afterExecute, and subclassing CountDownLatch so that threads waiting on the latch get interrupted and the executor shuts down.
So far, this is the subclassed countdown latch:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class AbortableCountDownLatch extends CountDownLatch {
protected boolean aborted = false;
public AbortableCountDownLatch(int count) {
super(count);
}
/**
* Unblocks all threads waiting on this latch and cause them to receive an
* AbortedException. If the latch has already counted all the way down,
* this method does nothing.
*/
public void abort() {
if( getCount() == 0 )
return;
this.aborted = true;
while(getCount() > 0)
countDown();
}
#Override
public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
final boolean rtrn = super.await(timeout,unit);
if (aborted)
throw new AbortedException();
return rtrn;
}
#Override
public void await() throws InterruptedException {
super.await();
if (aborted)
throw new AbortedException();
}
public static class AbortedException extends InterruptedException {
public AbortedException() {
}
public AbortedException(String detailMessage) {
super(detailMessage);
}
}
}
And the thread pool executor:
public class MyThreadPoolExecutor extends ThreadPoolExecutor {
private static final int RETRY_LIMIT = 3;
private Map<Runnable, Integer> retriedTasks = new ConcurrentHashMap<>();
private AbortableCountDownLatch latch;
public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue, AbortableCountDownLatch latch) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
this.latch = latch;
}
#Override
public void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
// If submit() method is called instead of execute()
if (t == null && r instanceof Future<?>) {
try {
Object result = ((Future<?>) r).get();
} catch (CancellationException e) {
t = e;
} catch (ExecutionException e) {
t = e.getCause();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
if (t != null) {
retriedTasks.put(r, retriedTasks.getOrDefault(r, 0) + 1);
System.out.println("Retries for " + r + " -> " + retriedTasks.get(r));
/* check to see if we have retried this task too many times, if so - shutdown */
if (retriedTasks.containsKey(r) && retriedTasks.get(r) > RETRY_LIMIT) {
System.err.println("Thread failed for more than " + RETRY_LIMIT + " times, aborting everything..");
this.latch.abort();
} else {
System.err.println("Thread threw exception " + t.getMessage() + ". Retry-ing task...");
execute(r);
}
} else {
/* clear any previous retry count for this runnable */
retriedTasks.remove(r);
}
}
}
And a main would be using them like this:
import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class MainProcessor {
public static void main(String[] args) {
AbortableCountDownLatch latch = new AbortableCountDownLatch(5);
ThreadPoolExecutor threadPoolExecutor = new MyThreadPoolExecutor(8, 8, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), latch);
for (int i = 0; i < 5; i++) {
threadPoolExecutor.submit(() -> {
System.out.println("Started thread " + Thread.currentThread().getName());
Random random = new Random();
try {
Thread.sleep(random.nextInt(7000));
} catch (InterruptedException e) {
e.printStackTrace();
}
if (random.nextBoolean()){
System.err.println("Thread " + Thread.currentThread().getName() + " failed - throwing exception..");
throw new RuntimeException("Thread " + Thread.currentThread().getName() + "failed! spectacularly :!");
}
else {
System.out.println("Thread " + Thread.currentThread().getName() + " finished.");
latch.countDown();
}
});
}
try {
latch.await();
} catch (InterruptedException e) {
threadPoolExecutor.shutdownNow();
}
threadPoolExecutor.shutdown();
}
}
Does this approach look correct? I don't particularly like that the latch has to be passed to both the thread pool executor and to the actual Runnable. Is there a standard way of achieving this? I am fine with a Scala version too.
I have seen others who suggest that the tasks should re-submit itself to the pool in case of failure, but that doesn't seem a good idea, as the task should only be responsible of the actual running logic, and not execution details.
You could use a Task-Wrapper that does the work, then it would be rather simple:
public class TaskWrapper implements Runnable
{
private Runnable task;
private int maxResubmits;
private ThreadPoolExecutor executor;
private CountDownLatch latch;
public TaskWrapper(Runnable task, int maxResubmits, ThreadPoolExecutor executor, CountDownLatch latch) {
this.task=task;
this.maxResubmits=maxResubmits;
this.executor=executor;
this.latch=latch;
executor.submit(this);
}
public void run() {
try {
task.run();
latch.countdoun();
}
catch(Exception e) {
maxResubmits--;
if(maxResubmits>0)
executor.submit(this);
else
{
latch.countdoun();
executor.shutdownNow()
}
}
}
}
You now only need to create the latch, call your tasks and then wait for the execution:
List<Runnable> tasks;
int maxResubmits;
CountDownLatch latch=new CountDownLatch(tasks.size());
tasks.forEach(task->new TaskWrapper(task,maxResubmits,executor,latch));
latch.await();
if(!executor.isShutdown())
executor.shutdown();
I need to perform some action 50 million items. I have written below code
AtomicInteger failCounter = new AtomicInteger(0);
long start = System.currentTimeMillis();
ExecutorService es = Executors.newFixedThreadPool(30);
List<String> allids = getItems();//50 million items from db
log.info(getAction() + " Total items found: " + allids.size());
allids.stream().forEach(s -> {
es.execute(new MyRunnable(s, failCounter));
});
es.shutdownNow();
try {
if (!es.awaitTermination(100, TimeUnit.SECONDS)) {
System.out.println("Still waiting...");
System.exit(0);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Exiting normally...");
log.info("counter: " + failCounter.get());
public class MyRunnable implements Runnable {
private final String id;
private final AtomicInteger failCounter;
RollupRunnable(String id, AtomicInteger failCounter) {
this.id = id;
this.failCounter = failCounter;
}
#Override
public void run() {
try {
//perform some action
} catch (Exception exception) {
failCounter.getAndIncrement();
log.error(
"Error in calling " + getAction() + " for id: " + id + " of :" + this.getClass()
.getSimpleName(),
exception);
}
}
}
But executor exists after processing first 30 items.
Am I doing something wrong.
Instead of es.shutdownNow(); use es.shutdown();
shutDownNow() halts the processing of all the tasks including the ones that are not even executed.
That's the reason why not all of the items are executed by the Executor framework.
Hi I'm a newbie to concurrency so I wrote a very basic program to see whether on a threads completion the future.isDone() method shows true, unfortunately it always shows "false" when I schedule the task with scheduledAtFixedRate method. However if I use schedule method it shows "true" of course the simple task does not rerun seconds later. Any suggestions or explanations to help me understand why this is the case would be much appreciated.
Thanks!
Here with the code:
package com.company;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) {
Main mn = new Main();
System.out.println("Main thread started...");
mn.runobjects();
System.out.println("Main thread stopping...");
}
#Test
public void runobjects(){
List<commonrun> Obj = new ArrayList<>();
Obj.add(new TestObj1());
Obj.add(new TestObj2());
Obj.add(new TestObj3());
ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
ScheduledFuture<?> futures1 = null;
ScheduledFuture<?> futures2 = null;
ScheduledFuture<?> futures3 = null;
int i=0;
for (commonrun obj : Obj){
if (i==0) {
futures1 = executor.schedule(() -> obj.runme(), 0, TimeUnit.SECONDS);
}
if (i==1) {
futures2 = executor.scheduleAtFixedRate(() -> obj.runme(), 0, 10, TimeUnit.SECONDS);
}
if (i==2) {
futures3 = executor.scheduleAtFixedRate(() -> obj.runme(), 0, 10, TimeUnit.SECONDS);
}
i++;
}
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 1 is done : "+ futures1.isDone());
System.out.println("Thread 2 is done : "+ futures2.isDone());
System.out.println("Thread 3 is done : "+ futures3.isDone());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.company;
public interface commonrun {
public void runme();
}
package com.company;
public class TestObj1 implements commonrun {
static int counter = 0;
#Override
public void runme() {
System.out.println("Object 1 Starting... run : " + counter);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Object 1 Stopping... run : " + counter);
counter++;
}
}
package com.company;
public class TestObj2 implements commonrun {
#Override
public void runme() {
System.out.println("Object 2 Starting...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Object 2 Stopping...");
}
}
package com.company;
public class TestObj3 implements commonrun {
#Override
public void runme() {
System.out.println("Object 3 Starting...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Object 3 Stopping...");
}
}
ScheduledExecutorService.scheduleAtFixedRate() schedules repetitive task. It will never (naturally) finish, so it won't become done. From method's documentation:
the task will only terminate via cancellation or termination of the
executor
Thus, only if you call future.cancel() or executor.terminate() will the task become done and future.isDone() will then return true.
While one could potentially expect that future becomes done as soon as first task's execution completes, this is not the case for the following reasons:
once future becomes done it cannot be "undone" ("done" is a terminal state for a future), so isDone cannot report current execution state of a repetitive job
once future becomes done it makes no sense to cancel it (there isn't anything to cancel) -- that would not fit a repetitive task, which won't run indefinitely until canceled.
I am trying to stop a java thread if it is running for 6000 milliseconds.
Below code to kill the Thread R1 is failed to stop the thread. could you please correct code?
I have tried this code with while (!Thread.currentThread().isInterrupted()) to stop the thread.
import java.time.Duration;
import java.time.Instant;
class ThreadDemo extends Thread {
private Thread t;
private String threadName;
ThreadDemo(String name) {
threadName = name;
System.out.println("Creating " + threadName);
}
#Override
public void run() {
System.out.println("Running " + threadName);
try {
while (!Thread.currentThread().isInterrupted()) {
for (int i = 100; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// Let the thread sleep for a while.
Thread.sleep(600);
}
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
Thread.currentThread().interrupt();
}
System.out.println("Thread " + threadName + " exiting.");
}
#Override
public void start() {
System.out.println("Starting " + threadName);
if (t == null) {
t = new Thread(this, threadName);
t.start();
}
}
}
public class Killthread {
public static void main(String args[]) throws InterruptedException {
Instant timeBefore = Instant.now();
ThreadDemo R1 = new ThreadDemo("Thread-1");
R1.start();
System.out.println("Afte thread start");
Thread.sleep(6001);
Instant timeAfter = Instant.now();
if (Duration.between(timeBefore, timeAfter).toMillis() > 6000) {
R1.interrupt();
// R1.stop();
System.out.println("Thread Interrupted due to Time limitation.");
}
}
}
You've got two problems in your code, firstly that you aren't sleeping your main thread long enough, and secondly that you're interrupting the wrong thread.
6001 ms isn't long enough to guarantee that your duration check will be true. When I run your code, the main method rarely enters the if block. If you change to it sleep for 6100 ms, it should consistently call the interrupt.
Your second problem is that you're interrupting R1, but you need to be interrupting t.
If you override interrupt() in ThreadDemo to pass the call down to t, then it will receive the interrupt and break its execution thread.
e.g.
#Override public void interrupt() {
t.interrupt();
}
The problem is, that you start a complete new, different and unnecessary thread in ThreadDemo::start.
#Override
public void start() {
System.out.println("Starting " + threadName);
if (t == null) {
t = new Thread(this, threadName);
t.start();
}
}
It should rather look like
#Override
public void start() {
System.out.println("Starting " + threadName);
super.start();
}
And get rid of that private Thread t; in ThreadDemo.
In please of calling t.start() from your overridden start method call super.start() which will call the start() of thread class, and is responsible to create new thread and register it with thread scheduler.