java simple thread, but it can't run - java

it's a simple java thread.
there are 2 threads, and it should be printed every 5 second.
there's no error.
but i just can't run.
please help me finding out what's wrong...
class MyThread extends Thread {
String message;
int delay;
public MyThread(String s, int d) {
message = s;
delay = d;
}
public void run() {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
System.out.println(message + "+" + delay );
}
}
}
public class applet {
public static void main(String[] args){
MyThread mt1, mt2;
mt1 = new MyThread("Hello", 5000);
mt2 = new MyThread("Bye ", 10000);
mt1.start();
mt2.start();
}
}

You are printing ONLY ONCE if an exception occurs...
Modify the run method to:
public void run() {
try {
Thread.sleep(delay);
System.out.println(message + "+" + delay );
} catch (InterruptedException e) {
System.err.println("error here" );
}
}

There are actually 2 mistakes in your program:
1. Print your message in the normal flow
So far you only print your message when you get an InterruptedException which is an exception that is thrown when your thread has been interrupted while sleeping. So instead of printing your message in the catch block, you are supposed to print it after the sleep as next:
try {
Thread.sleep(delay);
System.out.println(message + "+" + delay );
} catch (InterruptedException e) {
// Re-set the interrupted flag
Thread.currentThread().interrupt();
}
2. Add an infinite loop
As you wish to print your message every 5 seconds, you need to call sleep in an infinite loop otherwise your thread will print it only once and die, so the code should be at the end:
try {
while (true) {
Thread.sleep(delay);
System.out.printf("%s+%d%n", message, delay);
}
} catch (InterruptedException e) {
// Re-set the interrupted flag
Thread.currentThread().interrupt();
}
3. Bonus
Alternatively, you can use a ScheduledExecutorService to schedule your tasks with a fixed rate using the method scheduleAtFixedRate, your code would then be:
// Create a ScheduledExecutorService of 2 threads
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
// Schedule my task every 5 seconds starting in 5 seconds
executor.scheduleAtFixedRate(new MyTask("Hello", 5000), 5L, 5L, TimeUnit.SECONDS);
// Schedule my task every 10 seconds starting in 10 seconds
executor.scheduleAtFixedRate(new MyTask("Bye ", 10000), 10L, 10L, TimeUnit.SECONDS);
The class MyTask would simply be:
class MyTask implements Runnable {
String message;
int delay;
public MyTask(String s, int d) {
message = s;
delay = d;
}
public void run() {
System.out.printf("%s+%d%n", message, delay);
}
}

Related

Java thread hangs after CompletionService.take()

I've got simple test code:
public static void main(String[] args) {
CompletionService<Integer> cs = new ExecutorCompletionService<>(Executors.newCachedThreadPool());
cs.submit(new Callable<Integer>() {
public Integer call(){
try{
Thread.sleep(3000); // Just sleep and print
System.out.println("Sleeping thread: " + Thread.currentThread().getId());
}catch(InterruptedException e){
e.printStackTrace();
}
return 10;
}
});
try{
Future<Integer> fi = cs.take();
System.out.println(fi.get());
}catch(Exception e){
e.printStackTrace();
}
}
I run it, sleep 3 seconds, and prints
Sleeping thread: 14
10
But then it hangs there, the program doesn't end.
What's happening, how to make it finish?
As mentioned in the comments by tgdavies, your program will exit after +/- 60 seconds, because that is the default timeout for a thread without tasks in an ExecutorService created by Executors.newCachedThreadPool().
If you don't want to wait for 60 seconds, you should shutdown the executor service after you're done submitting tasks.
For example:
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
try {
CompletionService<Integer> cs = new ExecutorCompletionService<>(executorService);
cs.submit(new Callable<Integer>() {
public Integer call() {
try {
Thread.sleep(3000); // Just sleep and print
System.out.println("Sleeping thread: " + Thread.currentThread().getId());
} catch (InterruptedException e) {
e.printStackTrace();
}
return 10;
}
});
try {
Future<Integer> fi = cs.take();
System.out.println(fi.get());
} catch (Exception e) {
e.printStackTrace();
}
} finally {
executorService.shutdown();
}
}
Alternatively, configure the executor service to create daemon threads using a custom ThreadFactory. Only do this if it is not a problem that an executor service that is doing actual work gets "killed" when there are no more normal (non-daemon) threads.

ScheduledExecutorService waits for task to complete, does pending tasks pile up to ultimately interrupting main thred?

I was curious for my new implementation using ScheduledExecutorService in which the task is expected to finish within 100ms period and 0ms delay. But in case if there is system load and its taking say 550 ms, would there be a queue maintained by ScheduledExecutorService for those pending 4 tasks? And then run as soon as (0ms delay) first one is finished. And what if second execution takes 560 ms , would that add another 4 threads to its queue?
There is not documentation around that, or I might be overlooking it. But I want to make sure that the pile up of such executions would trigger to leak or overflow.
For example: below code, could main thread ever fail?
private static ScheduledExecutorService consumerThreadPool = Executors.newSingleThreadScheduledExecutor();
public static void main(String[] args) throws Exception {
consumerThreadPool.scheduleAtFixedRate(() -> performTask(), 0, 1, TimeUnit.MILLISECONDS);
}
private static void performTask () {
try {
Thread.sleep(550);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Your tasks will be skipped if they overrun the next scheduled time, you can verify easily with System.out.println and alter the sleep under 500ms to 5000ms:
public static void main(final String[] args) throws InterruptedException, ExecutionException
{
var executor = Executors.newScheduledThreadPool(1);
var count = new AtomicInteger();
Runnable task = () -> {
String desc = "run("+((System.currentTimeMillis() / 1000) % 60)+") "+Thread.currentThread().getName()+" count "+count.incrementAndGet();
System.out.println(desc);
if(count.get() == 50)
throw new RuntimeException("I give up!");
try
{
Thread.sleep(2500);
}
catch (InterruptedException e)
{
System.out.println("Thread "+Thread.currentThread().getName()+" INTERRUPTED");
}
};
var future = executor.scheduleAtFixedRate(task, 5000, 1000, TimeUnit.MILLISECONDS);
System.out.println("Calling future.get() ...");
try {
var res = future.get();
System.out.println("future.get()="+res);
}
catch(Exception e)
{
System.err.println("There was an exception:" +e);
// Decide between "continue" or "throw e" here
// ...
}
executor.shutdownNow();
System.out.println("shutdown complete");
}

Is there a way to completely stop a task in java?

I want a task to run at scheduled interval and timeout if it does not complete in required time and continue further iteration.
I have gone through the following answers, but it doesn't address my problem..
How do you kill a Thread in Java?
ExecutorService that interrupts tasks after a timeout
Consider the following case
BasicThreadFactory collectionFactory = new BasicThreadFactory.Builder()
.namingPattern("CollectionExecutor-%d")
.build();
// thread pool size is set 2
// 1-for scheduler thread which runs task and tracks timeout
// 2-for task itself
ScheduledExecutorService collectionExecuter =
Executors.newScheduledThreadPool(2, collectionFactory);
// fires collection every minute and if it is in between execution during
// scheduled time then waits for completion and executes immediately
// after it
//my task:
Runnable runnable= new Runnable() {
#Override
public void run() {
try {
System.out.println("Executed started");
Thread.sleep(2000);
System.out.println("Executed after .get method call.");
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.sleep(20000);
System.out.println("Executed even after .cancel method " +
"call (I want this to avoid this.)");
} catch (Exception e) {
e.printStackTrace();
}
}
};
Above task should run with an interval of 3 sec and stop if it takes more than 1 sec...Consider It is not possible to have complete task in single try catch block, now how could I stop the task to wait further in next sleep(20000) and continue with next iteration.
collectionExecuter.scheduleAtFixedRate(new Runnable() {//scheduler thread
#Override
public void run() {
try {
Future<?> future = collectionExecuter.submit(runnable);
try {
future.get(1, TimeUnit.SECONDS);
} catch (Exception e) {
future.cancel(true);
System.out.println("Collection thread did not " +
"completed in 1 Sec.Thread Interrupted");
}
} catch (Exception e) {
System.out.println("Unable to start Collection Thread");
}
}
}, 0, 3, TimeUnit.SECONDS);
}

Setting a maximum execution time for a method/thread

I have a method, which writes to the database. The requirement is to make sure that this method does not execute after a certain time elapses. If it returns before that, then nothing should be done.
The one basic approach that I can think of is doing something like this.
public class LimitedRuntime {
public static void writeToDb(){
// writes to the database
}
public static void main(String[] args) {
long totalExecutionTime = 8000L;
long startTime = System.currentTimeMillis();
while(System.currentTimeMillis() - startTime < totalExecutionTime )
{
writeToDb();
}
}
}
One problem with this approach is that even if the method returns before the max total execution time, even then the program halts so as to wait for the time to elapse.
How can I do this better (or maybe more correctly) ? And if we use Thread, how can we find out which Thread executes that method ?
You can do this by sending your job to an executor:
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(4);
Future<?> future = executor.submit(new Runnable() {
#Override
public void run() {
writeToDb(); // <-- your job
}
});
executor.shutdown(); // <-- reject all further submissions
try {
future.get(8, TimeUnit.SECONDS); // <-- wait 8 seconds to finish
} catch (InterruptedException e) { // <-- possible error cases
System.out.println("job was interrupted");
} catch (ExecutionException e) {
System.out.println("caught exception: " + e.getCause());
} catch (TimeoutException e) {
future.cancel(true); // <-- interrupt the job
System.out.println("timeout");
}
// wait all unfinished tasks for 2 sec
if(!executor.awaitTermination(2, TimeUnit.SECONDS)){
// force them to quit by interrupting
executor.shutdownNow();
}
}
There is also an AspectJ solution for that with jcabi-aspects library:
#Timeable(limit = 5, unit = TimeUnit.SECONDS)
public String writeToDb() {
// writeToDb
}
There is an article explaining it further: Limit Java Method Execution Time

In Java: how can I make thread watch over another thread?

Sorry if the question is quite simple. I am a beginner.
I have to create thread that calulates something, while the first thread works the other one have to measure if the first thread calculate the function in specified time. If not, it has to throw exception. Else it returns the answer.
I'd take the java.util.concurrent components - simple example
public void myMethod() {
// select some executor strategy
ExecutorService executor = Executors.newFixedThreadPool(1);
Future f = executor.submit(new Runnable() {
#Override
public void run() {
heresTheMethodToBeExecuted();
}
});
try {
f.get(1000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// do something clever
} catch (ExecutionException e) {
// do something clever
} catch (TimeoutException e) {
// do something clever
}
}
Have your thread notify a synchronization object when it is done and have your other thread wait x number of milliseconds for it to finish.
public class Main {
private static final Object mThreadLock = new Object();
static class DoTaskThread extends Thread {
public void run() {
try {
int wait = new Random().nextInt(10000);
System.out.println("Waiting " + wait + " ms");
Thread.sleep(wait);
} catch (InterruptedException ex) {
}
synchronized (mThreadLock) {
mThreadLock.notifyAll();
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
synchronized (mThreadLock) {
DoTaskThread thread = new DoTaskThread();
thread.start();
try {
// Only wait 2 seconds for the thread to finish
mThreadLock.wait(2000);
} catch (InterruptedException ex) {
}
if (thread.isAlive()) {
throw new RuntimeException("thread took too long");
} else {
System.out.println("Thread finished in time");
}
}
}
}
join is a lot simpler than using a lock.
join (millis)
Waits at most millis milliseconds
for this thread to die. A timeout of 0
means to wait forever.
Example code:
Thread calcThread = new Thread(new Runnable(){
#Override
public void run() {
//some calculation
}
});
calcThread.start();
//wait at most 2secs for the calcThread to finish.
calcThread.join(2000);
//throw an exception if the calcThread hasn't completed.
if(calcThread.isAlive()){
throw new SomeException("calcThread is still running!");
}
Have a look at http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#awaitTermination(long,%20java.util.concurrent.TimeUnit) which allows you to handle this without dealing with thread synchronization yourself.

Categories

Resources