Time limited

An attempt to build a Runnable , which should be completed within the specified period.

I am currently using java.util.Timer to interrupt a Runnable thread.

Timer starts immediately after running Runnable .

 import java.util.Timer; import java.util.TimerTask; public class test { Thread task; Timer timer; public void start(){ task = new Thread(new worker()); timer = new Timer("timer",true); task.start(); timer.schedule(new Terminator(),1000*2); } class worker implements Runnable{ @Override public void run() { for (int i = 0 ; i < 2; i++){ try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println("Test Interrupted !!"); return; } } System.out.println("Test Finished !!"); timer.cancel(); } } class Terminator extends TimerTask{ @Override public void run() { task.interrupt(); System.out.println("Test Terminated !!"); } } } 

But I suspect this leads to a race condition between Timer and Runnable themes: Runnable is about to end, and Timer also firing.

Could this lead to completion? and discontinued !! is printed? If so, how to avoid this?

Update:

It happens:

 11-09 21:14:40.741: INFO/System.out(31442): Test Finished !! 18 11-09 21:14:40.751: INFO/System.out(31442): Test Terminated !! 18 11-09 21:14:40.751: INFO/System.out(31442): Test Finished !! 19 11-09 21:14:40.751: INFO/System.out(31442): Test Terminated !! 19 
+4
source share
2 answers

Could this lead to completion? and discontinued !! is printed?

Yes. When the message β€œfinished” is printed, it is possible that the timer will light up before it is canceled.

 System.out.println("Finished !!"); // The timer can fire here. timer.cancel(); 

If this happens, both messages will be printed.


To avoid the problem, you can use synchronization.

 synchronized (someObject) { if (!finished) { finished = true; System.out.println("Finished !!"); timer.cancel(); } } 

And in the terminator:

 synchronized (someObject) { if (!finished) { finished = true; task.interrupt(); System.out.println("Test Terminated !!"); } } 

This prevents the printing of both forms of messages.

+4
source

Yes. If you want to avoid this, you need to use synchronize and common locking objects:

 public class test { private Object lock = new Object(); ... synchronized(lock) { System.out.println("Test Finished !!"); timer.cancel(); } ... synchronized(lock) { if( ! task.isRunning() ) return; task.interrupt(); System.out.println("Test Terminated !!"); } ... 
+4
source

Source: https://habr.com/ru/post/1445069/


All Articles