I have multiple threads of multiple types (Different classes). I want in case one of them throws an exception and dies to be replaced by another NEW thread. I am aware of the join thread function but how would I go about implementing them for 5 different type of threads such as in case type 1 thread dies is instantly replaced without having to wait for type 2 to die first.
This is some sample pseudo-code.
class1 implements runnable{
void run(){
try{
while(true){
repeat task
}
} catch(Exception e){
log error
}
}
}
class2 implements runnable{
void run(){
try{
while(true){
repeat task
}
} catch(Exception e){
log error
}
}
}
class3 implements runnable{
void run(){
try{
while(true){
repeat task
}
} catch(Exception e){
log error
}
}
}
public main(){
// start all threads .start()
}
I want in case one of them throws an exception and dies to be replaced by another NEW thread.
I don't quite understand why you can't do:
public void run() {
// only quit the loop if the thread is interrupted
while (!Thread.currentThread().isInterrupted()) {
try {
// do some stuff that might throw
repeat task;
} catch (Exception e) {
// recover from the throw here but then continue running
}
}
}
Why do you need to restart a NEW thread? Just because a task threw an exception doesn't mean that it is somehow corrupt and it needs a fresh one to work appropriately. If you are trying to catch all exceptions (including RuntimeException) then catch (Exception e) will do this. If you want to be really careful you can even catch Throwable in case there is a chance that Errors are being generated – this is relatively rare.
If you actually have multiple tasks (or really anytime you are dealing with threads), you should consider using the ExecutorService classes. See the Java tutorial.
// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// or you can create an open-ended thread pool
// ExecutorService threadPool = Executors.newCachedThreadPool();
// define your jobs somehow
threadPool.submit(new Class1());
threadPool.submit(new Class2());
...
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
So instead of forking a thread to do multiple tasks, you start a thread pool and it starts threads as necessary to accomplish a bunch of tasks. If a task fails, you could certain submit another task to the pool although that's a slightly strange pattern.
If you want to wait for all of the tasks to finish you'd use:
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
boolean shouldStop() {
// it's a good idea to think about how/when to stop ;)
return false;
}
void runThreadGivenType(final Runnable taskToRun) {
new Thread() {
#Override
public void run() {
try {
taskToRun.run();
} finally {
if (!shouldStop()) {
runThreadGivenType(taskToRun);
}
}
}
}.start();
}
public void main(String[] args) throws Exception {
runThreadGivenType(new Runnable() { public void run() { System.out.println("I'm almost immortal thread!"); throw new RuntimeException(); } });
TimeUnit.SECONDS.sleep(10);
}
and it's a good idea to think about executors to manage thread pools too. plain, [un/hand]-managed threads are not the best practice ;)
Related
I'm having trouble cleaning up my threads in a threaded application. I have various runnables that are kicked off using a thread pool. Most of these threads are normal runnables that only execute once on a Scheduled Fixed Rate. Two of them I have are scheduled to run once and have a while(true) loop in them. When I get to cleaning up the threads, it seems I'm having trouble calling ScheduledFuture.close(false) on the threads with the while loop in them. They don't seem to close.
An example of the format of these threads with while loops are:
public void run()
{
while (true)
{
QueryItem qi = null;
String query = null;
try
{
// This is a BlockingQueue!
qi = (QueryItem) FB2DatabaseRecorder.dbProcQueue.take();
query = qi.getQuery();
} catch (InterruptedException e)
{
errorLog.error("Unable to fetch message from message processing queue.");
}
// DO SOME STUFF
}
}
When I try to do the .close() on this thread, it's typically sitting at the blocking queue waiting for an item to come in. Before closing the threads I ensure that the queues are flushed as to not leave any data behind.
Is there a better way to close this type of thread? It seems like it is just not dying with handle.close(false);
A better way to shutdown your worker thread is to use Thread.interrupt().
Your worker thread is waiting on the take call, and the take call throws if the thread is interrupted. You can send an interrupt and manage the shutdown in the catch clause. In code,
package stackOv;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
class MyQueueWorker implements Runnable {
private BlockingQueue<Object> q;
MyQueueWorker(BlockingQueue<Object> q) {
this.q = q;
}
#Override
public void run() {
while (true) {
try {
Object item = q.take();
// work here
System.out.println("obj=" + item);
} catch (InterruptedException e) {
System.out.println("worker thread is interrupted");
break;
}
}
System.out.println("interrupted, exiting worker thread");
}
}
public class InterruptTake {
public static void main(String[] args) throws Exception {
BlockingQueue<Object> q = new LinkedBlockingQueue<>();
Thread worker = new Thread( new MyQueueWorker(q ), "worker" );
worker.start();
q.put("hello");
q.put("world");
q.put("waiting..");
Thread.sleep(1000);
worker.interrupt();
}
}
This question already has answers here:
How to properly stop the Thread in Java?
(9 answers)
Closed 9 years ago.
I am having a problem trying to stop a thread instantly after a certain amount of time has elapsed, because thread.stop and similar others have been depreciated.
The thread that I am trying to stop uses my mouse and I need to stop it so that I can use my mouse in other ways.
What I was thinking is the code below, which was just to make another thread to watch how long the main thread has been running and if it is alive, stop it, but I can't accomplish this.
public void threadRun(int a) {
Thread mainThread = new Thread(new Runnable() {
#Override
public void run() {
// does things with mouse which may need to be ended while they
// are in action
}
});
Thread watchThread = new Thread(new Runnable() {
#Override
public void run() {
if (timeFromMark(mark) > a) {
if (mainThread.isAlive()) {
// How can I stop the mainThread?
}
}
}
});
}
You need to define a class for your second thread that extends runnable and pass the first thread as an argument.
Then you can stop the first thread.
But instead of doing this manually, have a look at the Java ThreadPoolExecuter and its awaitTermination(long timeout, TimeUnit unit) method. (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html )
Will save a lot of work.
ExecutorService executor = Executors.newFixedThreadPool(1);
Runnable r = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
System.out.println("doing stuff");
Thread.sleep(10000);
System.out.println("finished");
} catch (InterruptedException e) {
System.out.println("Interrupted before finished!");
}
}
};
executor.execute(r);
executor.shutdown();
try {
executor.awaitTermination(1, TimeUnit.SECONDS);
executor.shutdownNow();
} catch (InterruptedException e) {
//
}
System.out.println("Thread worker forced down. Continue with Application...");
Produces:
doing stuff
Interrupted before finished!
Thread worker forced down. Continue with Application...
Last two messages are nearly equal in terms of time and may change positions (its two different threads, continuing)
Java has deprecated methods for explicitly killing another thread (like Thread.stop / Thread.destroy). The right way is to make sure the operations on the other thread can handle being told to stop (for example, they expect an InterruptedException, which means you can call Thread.interrupt() in order to stop it).
Taken from How do I kill a thread from another thread in Java?
Killing/stopping threads is a bad idea. That's why they deprecated those methods. It's better to ask the thread to stop. E.g., something like the example below. (But note: if "do_something()" takes a long time, then you might want to use an interrupt to abort whatever it is.)
import java.util.concurrent.atomic.AtomicBoolean;
public class Stoppable {
private AtomicBoolean timeToDie = new AtomicBoolean(false);
private Thread thread;
public void start() {
if (thread != null) {
throw new IllegalStateException("already running");
}
thread = new Thread(new Runnable() {
public void run() {
while (!timeToDie.get()) {
// do_something();
}
}
});
thread.start();
}
public void stop() throws InterruptedException {
timeToDie.set(true);
thread.join();
thread = null;
}
}
I have a task x that is executed continuously in a thread which will only stop when the boolean changes it's state to true. I have done some reading and there are 3 ways that I approach when killing threads that are in the code below. Which of the 3 methods is effective ? And if none of them aren't effective or correct kindly suggest a proper approach with some code for reference.
Below is the code :
public class MyTest {
private static class transaction {
private String param1,param2,param3, param4, param5;
public transaction (String param1,String param2,String param3,String param4,String param5){
this.param1=param1;
this.param2=param2;
this.param3=param3;
this.param4=param4;
this.param5=param5;
}
public String getParam1(){
return this.param1;
}
public String getParam2(){
return this.param2;
}
public String getParam3(){
return this.param3;
}
public String getParam4(){
return this.param4;
}
public String getParam5(){
return this.param5;
}
}
public static void processBatch(String workerName){
try{
java.util.List <transaction> transactions= new java.util.LinkedList<transaction>();
java.sql.ResultSet dbtrx=Database.db.execQuery((Object)"dbname.procname");
while(dbtrx.next()){// Takes a snapshot of the pending payments in the table and stores it into the list.
Object obj=new transaction (dbtrx.getString("col1"), dbtrx.getString("col2"), dbtrx.getString("col3"), dbtrx.getString("col4"), dbtrx.getString("col5"));
transactions.add((transaction)obj);
obj=null;
}
java.util.Iterator<transaction> iterate= transactions.iterator();
/* Processes the pending batch payments*/
while(iterate.hasNext()){
transaction trx=iterate.next();
/*Calls posting function here*/
System.out.println(workerName+":- Param1 : "+trx.getParam1()+" - Param2 : " +trx.getParam2()+
" - Param3 : "+ trx.getParam3()+" - Param4 : "+ trx.getParam4()+" - Param5 : "+ trx.getParam5());
iterate.remove();
}
/*cleaning object references*/
dbtrx=null;
transactions=null;
iterate=null;
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String [] args) throws InterruptedException{
volatile boolean stop=false;
Object hold= new Object();
new Thread("Batch Worker A"){
#Override
public void run(){
while(true){
if(stop!=true){
processBatch(Thread.currentThread().getName());
}else{
try{
Thread.sleep(0);
Thread.currentThread().interrupt();
}catch(java.lang.InterruptedException e){
Thread.currentThread().interrupt();
break;
}
}
}
}}.start();
new Thread("Batch Worker B"){
#Override
public void run(){
try{
while(stop!=true){
processBatch(Thread.currentThread().getName());
}
Thread.sleep(0);
Thread.currentThread().interrupt();
}catch(java.lang.InterruptedException e){
Thread.currentThread().interrupt();
}
}}.start();
new Thread("Batch Worker C"){
#Override
public void run(){
while(!Thread.currentThread().isInterrupted()){
if(stop!=true){
processBatch(Thread.currentThread().getName());
}else{
Thread.currentThread().interrupt();
}
}
}}.start();
}
}
}
The recommended approach is to use the thread's interrupted flag to signal the thread loop to terminate. There's no reason to use two flags (stopped and the interrupted flag) where one will do, and you don't seem to be using the interrupted flag for anything else.
See the Java tutorial subject Interrupts for a more extensive discussion and examples.
Why not simply this way:
new Thread("Batch Worker A"){
#Override
public void run() {
while(!stop){
processBatch(Thread.currentThread().getName());
}
}
}}.start();
Alternatively, use Thread.interrupt() like so:
new Thread("Batch Worker A"){
#Override
public void run() {
while(!interrupted()){
processBatch(Thread.currentThread().getName());
}
}
}}.start();
but then you need to keep reference to all the threads, and interrupt them all, so the boolean flag might be simpler (be sure to make it volatile).
In all of your examples, you aren't really killing the thread, you are stopping the batch from processing more items.
To understand the difference, note that none of your methods would actually stop the thread while the thread is within the processBatch function.
There are some things to take note of:
There is no point in calling Interrupt() on your current thread. The idea behind Interrupt is for external threads to call it. In your case, you can just as well throw an exception, or return from the run() function (which would shut down the thread automatically).
Even interrupt() can't in many situations stop a thread if that thread is locked outside java ,such as thread waiting for IO (if not using NIO), including a socket, which is what the database connection is, you'll need to design a different way to stop a thread inside IO (usually by doing a timeout, but there are other ways).
if you goal is simply to stop the next batch from happing use the code from Joonas :
new Thread("Batch Worker A"){
#Override
public void run() {
while(!stop){
processBatch(Thread.currentThread().getName());
}
}
}}.start();
if your goal is to interrupt the process while running the batch, you can just as well do:
public static void main(String[] args) {
var t =new Thread("Batch Worker A"){
#Override
public void run() {
processBatch(Thread.currentThread().getName());
}
}.start();
t.interrupt();
}
in general interrupt is the preferred method, and using a local scoped variable and anonymous classes is a really bad idea (use a static variable, or better an injected interface with a function to check if the thread should continue).
I am trying to write a part of a multithreaded program where each thread from a fixed thread pool tries to fetch an object from a Queue and if the Queue is empty the thread waits.
The problem I am experiencing is that the memory used by the program keeps increasing.
public class Ex3 {
public static LinkedBlockingQueue<Integer> myLBQ = new LinkedBlockingQueue<Integer>(10);
public static void main(String argc[]) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(3);
myLBQ.add(new Integer(1));
for (;;) {
executor.execute(new MyHandler(myLBQ));
}
}
}
class MyHandler implements Runnable {
LinkedBlockingQueue<Integer> myLBQ;
MyHandler(LinkedBlockingQueue<Integer> myLBQ) {
this.myLBQ = myLBQ;
}
public void run() {
try {
myLBQ.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I don't understand why the executor.execute keeps firing when the threads should be waiting for an item to be added to the Queue. How do I modify my code to reflect this?
This adds tasks to the executor as fast as it can.
for (;;) {
executor.execute(new MyHandler(myLBQ));
}
This will consume about 200 MB per second. It doesn't have anything to do with whether there are tasks to perform or not.
If you don't want to do this I suggest you move the loop to the runnable and add only one. This will cause it to wait for tasks forever.
A better approach is to use the ExecutorService's builtin queue to queue tasks.
ExecutorService executor = Executors.newFixedThreadPool(3);
final int taskId = 1;
executor.submit(new Runnable() {
#Override
public void run() {
doSomething(taskId);
}
});
executor.shutdown();
This does the same thing, but is much simpler IMHO.
it's because you're creating a gazillion instances of MyHandler and inserting them in the internal queue of the executor.
That infinite for loop is quite mean.
Is there a standard nice way to call a blocking method with a timeout in Java? I want to be able to do:
// call something.blockingMethod();
// if it hasn't come back within 2 seconds, forget it
if that makes sense.
Thanks.
You could use an Executor:
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Object> task = new Callable<Object>() {
public Object call() {
return something.blockingMethod();
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
// handle the timeout
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
} finally {
future.cancel(true); // may or may not desire this
}
If the future.get doesn't return in 5 seconds, it throws a TimeoutException. The timeout can be configured in seconds, minutes, milliseconds or any unit available as a constant in TimeUnit.
See the JavaDoc for more detail.
You could wrap the call in a FutureTask and use the timeout version of get().
See http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/FutureTask.html
See also Guava's TimeLimiter which uses an Executor behind the scenes.
It's really great that people try to implement this in so many ways. But the truth is, there is NO way.
Most developers would try to put the blocking call in a different thread and have a future or some timer. BUT there is no way in Java to stop a thread externally, let alone a few very specific cases like the Thread.sleep() and Lock.lockInterruptibly() methods that explicitly handle thread interruption.
So really you have only 3 generic options:
Put your blocking call on a new thread and if the time expires you just move on, leaving that thread hanging. In that case you should make sure the thread is set to be a Daemon thread. This way the thread will not stop your application from terminating.
Use non blocking Java APIs. So for network for example, use NIO2 and use the non blocking methods. For reading from the console use Scanner.hasNext() before blocking etc.
If your blocking call is not an IO, but your logic, then you can repeatedly check for Thread.isInterrupted() to check if it was interrupted externally, and have another thread call thread.interrupt() on the blocking thread
This course about concurrency https://www.udemy.com/java-multithreading-concurrency-performance-optimization/?couponCode=CONCURRENCY
really walks through those fundamentals if you really want to understand how it works in Java. It actually talks about those specific limitations and scenarios, and how to go about them in one of the lectures.
I personally try to program without using blocking calls as much as possible. There are toolkits like Vert.x for example that make it really easy and performant to do IO and no IO operations asynchronously and in a non blocking way.
I hope it helps
There is also an AspectJ solution for that with jcabi-aspects library.
#Timeable(limit = 30, unit = TimeUnit.MINUTES)
public Soup cookSoup() {
// Cook soup, but for no more than 30 minutes (throw and exception if it takes any longer
}
It can't get more succinct, but you have to depend on AspectJ and introduce it in your build lifecycle, of course.
There is an article explaining it further: Limit Java Method Execution Time
I'm giving you here the complete code. In place of the method I'm calling, you can use your method:
public class NewTimeout {
public String simpleMethod() {
return "simple method";
}
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Callable<Object> task = new Callable<Object>() {
public Object call() throws InterruptedException {
Thread.sleep(1100);
return new NewTimeout().simpleMethod();
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(1, TimeUnit.SECONDS);
System.out.println(result);
} catch (TimeoutException ex) {
System.out.println("Timeout............Timeout...........");
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
} finally {
executor.shutdown(); // may or may not desire this
}
}
}
Thread thread = new Thread(new Runnable() {
public void run() {
something.blockingMethod();
}
});
thread.start();
thread.join(2000);
if (thread.isAlive()) {
thread.stop();
}
Note, that stop is deprecated, better alternative is to set some volatile boolean flag, inside blockingMethod() check it and exit, like this:
import org.junit.*;
import java.util.*;
import junit.framework.TestCase;
public class ThreadTest extends TestCase {
static class Something implements Runnable {
private volatile boolean stopRequested;
private final int steps;
private final long waitPerStep;
public Something(int steps, long waitPerStep) {
this.steps = steps;
this.waitPerStep = waitPerStep;
}
#Override
public void run() {
blockingMethod();
}
public void blockingMethod() {
try {
for (int i = 0; i < steps && !stopRequested; i++) {
doALittleBit();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public void doALittleBit() throws InterruptedException {
Thread.sleep(waitPerStep);
}
public void setStopRequested(boolean stopRequested) {
this.stopRequested = stopRequested;
}
}
#Test
public void test() throws InterruptedException {
final Something somethingRunnable = new Something(5, 1000);
Thread thread = new Thread(somethingRunnable);
thread.start();
thread.join(2000);
if (thread.isAlive()) {
somethingRunnable.setStopRequested(true);
thread.join(2000);
assertFalse(thread.isAlive());
} else {
fail("Exptected to be alive (5 * 1000 > 2000)");
}
}
}
You need a circuit breaker implementation like the one present in the failsafe project on GitHub.
Try this. More simple solution. Guarantees that if block didn't execute within the time limit. the process will terminate and throws an exception.
public class TimeoutBlock {
private final long timeoutMilliSeconds;
private long timeoutInteval=100;
public TimeoutBlock(long timeoutMilliSeconds){
this.timeoutMilliSeconds=timeoutMilliSeconds;
}
public void addBlock(Runnable runnable) throws Throwable{
long collectIntervals=0;
Thread timeoutWorker=new Thread(runnable);
timeoutWorker.start();
do{
if(collectIntervals>=this.timeoutMilliSeconds){
timeoutWorker.stop();
throw new Exception("<<<<<<<<<<****>>>>>>>>>>> Timeout Block Execution Time Exceeded In "+timeoutMilliSeconds+" Milli Seconds. Thread Block Terminated.");
}
collectIntervals+=timeoutInteval;
Thread.sleep(timeoutInteval);
}while(timeoutWorker.isAlive());
System.out.println("<<<<<<<<<<####>>>>>>>>>>> Timeout Block Executed Within "+collectIntervals+" Milli Seconds.");
}
/**
* #return the timeoutInteval
*/
public long getTimeoutInteval() {
return timeoutInteval;
}
/**
* #param timeoutInteval the timeoutInteval to set
*/
public void setTimeoutInteval(long timeoutInteval) {
this.timeoutInteval = timeoutInteval;
}
}
example :
try {
TimeoutBlock timeoutBlock = new TimeoutBlock(10 * 60 * 1000);//set timeout in milliseconds
Runnable block=new Runnable() {
#Override
public void run() {
//TO DO write block of code
}
};
timeoutBlock.addBlock(block);// execute the runnable block
} catch (Throwable e) {
//catch the exception here . Which is block didn't execute within the time limit
}
In special case of a blocking queue:
Generic java.util.concurrent.SynchronousQueue has a poll method with timeout parameter.
Assume blockingMethod just sleep for some millis:
public void blockingMethod(Object input) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
My solution is to use wait() and synchronized like this:
public void blockingMethod(final Object input, long millis) {
final Object lock = new Object();
new Thread(new Runnable() {
#Override
public void run() {
blockingMethod(input);
synchronized (lock) {
lock.notify();
}
}
}).start();
synchronized (lock) {
try {
// Wait for specific millis and release the lock.
// If blockingMethod is done during waiting time, it will wake
// me up and give me the lock, and I will finish directly.
// Otherwise, when the waiting time is over and the
// blockingMethod is still
// running, I will reacquire the lock and finish.
lock.wait(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
So u can replace
something.blockingMethod(input)
to
something.blockingMethod(input, 2000)
Hope it helps.