I want to check whether file exists at required location or not.
I am creating one text file from java e.g. abc.txt. I am going to use this file in some other program let's say a CAD program to generate a drawing. After completion of CAD process, it generates a file with some extension e.g. '.cad'. This drawing generation will take some time.
I am going to use the same '.cad' file in another program let's say an analysis software to analyse the generated drawing.
Now my problem is, I want to check whether the '.cad' file is generated or not. As the generation of .cad file takes time, without this file I can't proceed further i.e. I can't provide this file to next step (i.e. to analysis software).
So, is there any way in java, such that I can check for existence of .cad file for some time (let's say 120 seconds). And if I find the file then only proceed to next step.
I searched about the method file.exists() but it checks only once.
Please give me some hint.
Thank you all in advance!
I guess that you could use daemon for make your task at the background, hope it be helpful friend!
public class DaemonFolder extends Thread {
#SuppressWarnings("deprecation") // stop();
public static void main(String[] args) {
System.out.println("Pulsar enter para finalizar");
DaemonFolder daemonn= new DaemonFolder();
Scanner finalize= new Scanner(System.in);
finalize.nextLine();
daemonn.stop();
finalize.close();
System.out.println("Programa finalizado!");
}
public DaemonFolder() {
setDaemon(true); // Daemon threads in Java are like a service providers for other threads or objects running in the same process as the daemon thread
start();
}
#Override
public void run() {
while (true) {
try {
sleep(5000);
if (new File("anonymous.txt").exists()){
System.out.println("exists");
//DO SOMETHING
} else {
System.out.println("not exists");
}
} catch (Exception e){
e.printStackTrace();
}
}
}
}
You could for example write a for-loop that counts from 0 to 119 and there do the exists check, if it was successful call the next step, if not call Thread.sleep(1000) to wait a second before the next check.
Or you could for example schedule a TimerTask in a Timer to be run each second and in the TimerTask do the exists check and if maximum time is elapsed abort or if check goes well do the next step and abort.
There are plenty ways to do it, these were just two of them.
You need create cycle with your method and Thread.sleep(120000).
Snmth. like this:
while(true) {
if (file.exists()) {
break;
} else {
Thread.sleep(120000);
}
}
Related
I've just put together one of my first full Java programs for practice. It is a simple snap game but I'm not happy with the method for the actual "Snap" condition. I may be being fussy but I wonder if there is something better someone could suggest?
public static boolean snap() {
Scanner response = new Scanner(System.in);
double compReflex = (Math.random() * (1000 - 250 + 1)) + 250;
long reflex = Math.round(compReflex);
long startTime = System.currentTimeMillis();
System.out.println("go");
response.nextLine();
if (System.currentTimeMillis() > startTime + reflex) {
System.out.println("I win");
response.close();
return false;
} else {
System.out.println(System.currentTimeMillis() - startTime);
System.out.println("Well done");
response.close();
return true;
}
}
The issue is I would like the else clause to happen immediately if a button was pressed and the if=True clause to happen automatically after the reflex delay if the button isn't pressed. At the moment enter has to be pressed and then the computer judges who had the shortest reaction time. Which isn't snap...
I looked at KeyListeners but they only seem to be available for UI's such as JSwing? I also looked at thread interruption but couldn't work out how to trigger a thread interrupt and then handle the exceptions with the correct program flow? Or is it is even possible?
I think it needs to be a multi-threaded solution but don't fully have a handle on concurrency/multi-threading yet so any really good learning resources appreciated in addition to solutions.
If the console API weren't so dreadfully old, you could simply do something like
try {
System.in.readLine(100, TimeUnit.MILLIS);
System.out.println("You win!");
} catch (InterruptedException e) {
System.out.println("Too slow!");
}
but unfortunately, the API to read from a console was defined in the very first release of the Java programming language, and not reworked since, so it doesn't allow reading with a timeout. If a thread reads from an InputStream, it won't stop reading until there is data, the InputStream itself signals an error, or the entire JVM exits.
So if you really want to do this, you'd need something like this:
public static void main(String[] args) {
var readerThread = new Thread(() -> {
try (var scanner = new Scanner(System.in)) {
scanner.nextLine();
gameOver(true);
}
});
readerThread.setDaemon(true); // this thread should not inhibit JVM termination
readerThread.start();
System.out.println("Go!");
sleep(500, TimeUnit.MILLISECONDS);
gameOver(false);
}
static void sleep(int duration, TimeUnit unit) {
try {
Thread.sleep(unit.toMillis(duration));
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
synchronized static void gameOver(boolean victory) {
if (!over) {
System.out.println(victory ? "You win!" : "I win!");
over = true;
}
}
static boolean over;
A few things to note here:
Since the two threads race to gameOver, we need to ensure they don't both execute it. By making the method synchronized, we ensure that the threads will execute it after each other, and by setting a boolean, we can detect whether the other thread was faster.
everything is static because we can't cancel the reading thread. Granted, we could keep it running and reuse it for the next instance of the game, but it would eat any console input in the meantime (such as the answer to "do you want to try again?"), which is annoying. So I am not going to pretend that this solution is nice and reusable, and thus can make my life easier by making everything static.
the try-with-resources statement is a compact way to close a resource (such as a Scanner) once we are done with it.
the utility method for sleep is just to move the pointless, but required, catch block out of the main method, so the main method is easier to read.
Below is diagram that shows what I'm trying to do : it is just 2 programs. One is a simple Child program that writes out integers every 2 seconds, line-by-line .
The other is a Parent program that monitors the log file ( just a very basic text file). If the log file doesn't get modified within 5 seconds, then it should restart the Child program (via a batch file ); then continue normally.
My code for the child class is here:
package fileiotestapplication;
import java.io.*;
import java.io.IOException;
import java.util.*;
public class WriterClass {
#SuppressWarnings("oracle.jdeveloper.java.insufficient-catch-block")
public WriterClass() {
super();
int[] content = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,};
String[] friends = {"bob",};
File file = new File("/C:/Java_Scratch/someFile.txt");
// if file does not exists, then create it
try {
if (!file.exists()) {
file.createNewFile();
}
for (int i = 0 ; i < content.length; i++)
{
PrintStream bw = new PrintStream( new FileOutputStream(file, true) );
System.out.println("testing " + i);
bw.println( String.valueOf(content[i]) );
bw.close();
Thread.sleep(2500);
}
System.out.println("Done");
} catch (IOException ioe) {
// TODO: Add catch code
ioe.printStackTrace();
}
catch (InterruptedException ioe) {
// TODO: Add catch code
ioe.printStackTrace();
}
//someIS.println(i);
System.out.println("This is OK");
}
public static void main(String[] args) {
WriterClass writerClass = new WriterClass();
}
}
The source code
And I linked here my current code for the Parent class.
What I'm now trying to do is add in some logic that catches when the child class stops writing output. What I'd like to do is count all the lines in the log file; and then compare them every 5 seconds, is this a good way (the alternative would be - to keep checking to see if the file got modified at all)?
EDIT: The suggestion below to use waitFor() indeed helps, though I'm still working out details : it is generally like :
try {
/* StackOverflow code */
for ( ; ; ) {
ProcessBuilder pb = new ProcessBuilder("TheBatchFile.bat");
pb.directory(new File("C://Java_Scratch_//Autonomic_Using_Batch//"));
Process p = pb.start();
p.waitFor();
}
/* end - StackOverflow code */
}
catch (IOException i) {
i.printStackTrace();
}
catch (InterruptedException i) {
i.printStackTrace();
}
This will get very slow as the file keeps growing in size. A simpler way would be to simply check the last modification time of the file. Assuming that the reason the child program might stop writing to the file is that the program terminates (rather than e.g. hanging in an infinite loop), it is probably better to directly monitor the child process itself rather than relying on observing the effects of the process. This is particularly convenient if the parent process can be responsible for starting the program in the first place.
This can be done with the ProcessBuilder and Process classes in Java 8. Copying from the documentation, you can start the process like this (if you only want to monitor whether it's running or not):
ProcessBuilder pb = new ProcessBuilder("TheBatchFile.bat", "Argument1", "Argument2");
pb.directory(new File("/path/to/working/dir"));
Process p = pb.start();
Then, you can simply call p.waitFor(); to wait for the process to terminate. Do this in a loop, and you have your automatic-restarting-of-child behavior.
You can use the directory watch service:
https://docs.oracle.com/javase/tutorial/essential/io/notification.html
You can configure a path or a file and register a watcher.
The watcher gets a notification every time a file is changed. You can store this timestamp of a notification for later use.
For details see my link above.
You may then use a Timer or a Thread to check last modification.
While your method of creating a text file, and using a batch script is feasible, there is a better way to approach it. This is a standard problem to approach with multitasking, and by creating a couple threads, it is not too difficult at all.
Using threads has several advantages over going externally "around" the system with batch files and multiple programs. For starters, these may include:
Keeping everything together makes the project much tidier, cleaner,
and marginally easier to distribute.
It is easier to implement. Sure threads may seem confusing if you have never used them, but they are the lesser evil in my opinion, then all the steps involved in going around them. As I hope to show below, implementing this problem with threads is not hard.
Improved performance, as the very expensive operations of file IO, and spawning the batch file are avoided. Threads also have improved performance over processes in most cases because they are easier to spawn, and multithreading sees performance improvements on a wider range of processors than multiprocessing by being less reliant on having several cores.
No sketchy overlap between when one program is reading the file, while the other is writing to it simultaneously. These kind of situations are best avoided when possible.
Maintains Java's impressive cross platform abilities, because you are not using batch which is not cross platform. This might not be important to you for this project, but you may come across something in the future with a similar problem, where this is more important, and so you will have practice implementing it.
You learn better by using threads the "right way" instead of
developing bad habits by using a more hacky approach. If this is a
learning project, you might as well learn it right.
I went ahead and coded up the approach that I would most likely use to solve the problem. My code has a child thread the counts every two seconds, and a parent thread that monitors the child, and restarts it if the child goes five seconds without counting. Let's examine my program to give you a good idea of how it is working.
First, here is the class for the parent:
public class Parent {
private Child child;
public Parent(){
child = new Child(this);
child.start();
}
public void report(int count){ //Starts a new watchdog timer
Watchdog restartTimer = new Watchdog(this, count);
restartTimer.start();
}
public void restartChild(int currentCount){
if (currentCount == child.getCount()){ //Check if the count has not changed
//If it hasn't
child.kill();
child.start();
}
}
public static void main(String[] args){
//Start up the parent function, it spawns the child
new Parent();
}
}
The main function in there can be put somewhere else if you want, but to start everything up, just instantiate a parent. The parent class has an instance of the child class, and it starts up the child thread. The child will report it's counting to the parent with the report method, which spawns a watchdog timer (more on that in a second) that will call restartChild after five seconds with the current count. RestartChild, restarts the child thread, if the count is still the same as the one provided.
Here is the class for the watchdog timer:
class Watchdog implements Runnable { //A timer that will run after five seconds
private Thread t;
private Parent parent;
private int initialCount;
public Watchdog(Parent parent, int count){ //make a timer with a count, and access to the parent
initialCount = count;
this.parent = parent;
}
public void run() { //Timers logic
try {
Thread.sleep(5000); // If you want to change the time requirement, modify it here
parent.restartChild(initialCount);
} catch (InterruptedException e) {
System.out.println("Error in watchdog thread");
}
}
public void start () // start the timer
{
if (t == null)
{
t = new Thread (this);
t.start ();
}
}
}
This watchdog timer is a thread that the parent will run with the start method. The parent sends itself as a parameter so that we can call the restartChild function of the parent.It stores the count, because when it runs after five seconds, restartChild will check if the count has changed.
And finally, here is the child class
public class Child implements Runnable{
private Thread t;
public int counter = 0;
private boolean running;
private Parent parent; // Record the parent function
public Child(Parent parent){
this.parent = parent;
}
private void initializeAll(){
counter = 0;
running = true;
}
public int getCount(){
return counter;
}
#Override
public void run() {
while((counter <= 100)&&(running)){
//The main logic for child
counter +=1;
System.out.println(counter);
parent.report(counter); // Report a new count every two seconds
try {
Thread.sleep(2000); // Wait two seconds
} catch (InterruptedException e) {
System.out.println("Thread Failed");
}
}
}
public void start(){ //Start the thread
initializeAll();
t = new Thread(this);
t.start();
}
public void kill(){ //Kill the thread
running = false;
}
}
This is also a thread, thus it implements runnable, and in that regard acts a lot like the watchdog. Run() is the main method of the child thread, this is where your logic goes that gets called when you start it. Starting the child with start() sets all the variables to their defaults, and then begins the run() logic. The logic in run is wrapped in if(running), because that lets us kill the thread internally by setting running to false.
Currently, all the child does right now is increment it's counter, output it to console, and then report the activity to the parent, 100 times, every two seconds. You will likely want to remove the condition stopping it after count passes 100, but I included it, so that the parent would eventual have cause to restart the child. To change the behavior, look at the child's run method, that is where all the main action is at.
My problem is: I have a class which accepts files in a directory. Whenever the first object arrives it starts some timer to perform a compress on all the files in a directory which arrive during the next 60 seconds.
This raises two requirements:
1) I need to be able to check if the "countdown" is already running when a new file arrives. I don't want file2 to arrive 15 seconds after file1, then they get compressed together 45 seconds later only to have a second scheduled task fire 15 seconds after the first completed (to an empty directory).
2) Smart batching / non-constant polling. For example, if file1 arrives at time=0 and file2 arrives at time=59s, they would be compressed together. However, if file3 doesn't arrive until time=89s, and file4 arrives at time=129s, I want to make sure the next "compress" operation is not happening at timer=120s, but rather at timer=149s (60 seconds after file3 arrived).
In other words: only one timer/countdown should ever be running. If it's the first file since a compression, it should trigger a new one, but otherwise it should just be ignored.
I'm looking into java.util.Timer and Java.util.concurent.ScheduledExecutorService as solutions, but both seem built for having multiple processes, which I am trying to avoid.
Is there any better solution for this?
Here is an example code:
private Thread countDownThread;
public synchronized void onNewFile() {
startCountDownThreadIfNotYetRunning();
}
public synchronized void resetThread() {
if(uncompressedFilesExist()) {
startCountDownThreadIfNotYetRunning();
}
}
public synchronized void startCountDownThreadIfNotYetRunning() {
if(countDownThread == null) {
new Thread(new CompressionTask()).start();
}
}
private class CompressionTask implements Runnable {
#Override
public void run() {
try {
Thread.sleep(60 * DateUtils.MILLIS_PER_SECOND);
compressDirectoryContents();
resetThread();
}
catch (InterruptedException e) { }
}
}
When onNewFile() is called it tries to start a new countDownThread if it is not already running.
This thread waits for 60 seconds and starts compression.
The last step resetThread() is a bit tricky. If we simply call:
countDownThread = null;
the code would not be thread-safe. First of all change made to countDownThread might not be visible by other threads. Moreover if new file appears between compressDirectoryContents() and simple assignment, it would get lost. That's why all operations are synchronized using the same lock.
Because both onNewFile() and resetThread() are guarded by the same lock, it is not possible that new file appears but the count-down thread is not started.
Note that you don't need any fancy Timers or ScheduleExecutorService - creating a single thread every minute isn't an overkill.
I am trying to program a game in which I have a Table class and each person sitting at the table is a separate thread. The game involves the people passing tokens around and then stopping when the party chime sounds.
how do i program the run() method so that once I start the person threads, they do not die and are alive until the end of the game
One solution that I tried was having a while (true) {} loop in the run() method but that increases my CPU utilization to around 60-70 percent. Is there a better method?
While yes, you need a loop (while is only one way, but it is simplest) you also need to put something inside the loop that waits for things to happen and responds to them. You're aiming to have something like this pseudocode:
loop {
event = WaitForEvent();
RespondToEvent(event);
} until done;
OK, that's the view from 40,000 feet (where everything looks like ants!) but it's still the core of what you want. Oh, and you also need something to fire off the first event that starts the game, obviously.
So, the key then becomes the definition of WaitForEvent(). The classic there is to use a queue to hold the events, and to make blocking reads from the queue so that things wait until something else puts an event in the queue. This is really a Concurrency-101 data-structure, but an ArrayBlockingQueue is already defined correctly and so is what I'd use in my first implementation. You'll probably want to hide its use inside a subclass of Thread, perhaps like this:
public abstract class EventHandlingThread<Event> extends Thread {
private ArrayBlockingQueue<Event> queue = new ArrayBlockingQueue<Event>();
private boolean done;
protected abstract void respondToEvent(Event event);
public final void postEvent(Event event) throws InterruptedException {
queue.put(event);
}
protected final void done() {
done = true;
}
public final void run() {
try {
while (!done) {
respondToEvent(queue.take());
}
} catch (InterruptedException e) {
// Maybe log this, maybe not...
} catch (RuntimeException e) {
// Probably should log this!
}
}
}
Subclass that for each of your tasks and you should be able to get going nicely. The postEvent() method is called by other threads to send messages in, and you call done() on yourself when you've decided enough is enough. You should also make sure that you've always got some event that can be sent in which terminates things so that you can quit the gameā¦
I would look into Locks and Conditions. This way you can write code that waits for a certain condition to happen. This won't take a lot of CPU power and is even much more efficient and better performing than sleeping .
To make a thread run for an infinite time:
final Object obj = new Object();
try {
Thread th = new Thread(new Runnable() {
public void run() {
synchronized(obj) {
try {
System.out.println("Waiting");
obj.wait();
System.out.println("Done waiting");
}catch(Exception ex) {
ex.printStackTrace();
}
}
}
});
th.start();
System.out.println("Waiting to join.");
// Dont notify; but wait for joining. This will ensure that main thread is running always.
th.join();
System.out.println("End of the Program");
} catch(Exception ex) {
ex.printStackTrace();
}
You may add Thread.sleep() with appropriate time to minimize useless loop iterations.
Another solution is using synchronization. While threads are not required to do anything, they enter into a sleeping state on a monitor using the wait() method, and then when the turn comes, required thread is woken up by the notify() method.
Actor model seems suitable for this scenario. Each person sitting on the table and the table itself can be modelled as actors and the event of passing the tokens and starting and stopping of the game can be modelled as messages to be passed between the actors.
As a bonus, by modelling the scenario as actors you get rid of explicit manipulation of threads, synchronization and locking.
On JVM I will prefer using Scala for modelling actors. For Java you can use libraries like Kilim. See this post for a comparison of Actor model related libraries in Java.
One Way is to use while loop but keep a check i.e
while(true){
if(condition!=true){
Thread.sleep(time);
}else{
break;
}
}
This way if your condition says game is not over it will keep person thread at sleep and memory consumption will be very low.
You should test for a condition in the while loop:
while (!gameOver)
{
do_intersting_stuff();
}
Heavy CPU load is typical for busy wait. Is your loop actually just checking a flag over and over, like
while (!gameOver)
{
if (actionNeeded)
{
do_something();
}
}
you might change to another notification system to sleep and wake up, as this just burns CPU time for nothing.
I have a method that I would like to call. However, I'm looking for a clean, simple way to kill it or force it to return if it is taking too long to execute.
I'm using Java.
to illustrate:
logger.info("sequentially executing all batches...");
for (TestExecutor executor : builder.getExecutors()) {
logger.info("executing batch...");
executor.execute();
}
I figure the TestExecutor class should implement Callable and continue in that direction.
But all i want to be able to do is stop executor.execute() if it's taking too long.
Suggestions...?
EDIT
Many of the suggestions received assume that the method being executed that takes a long time contains some kind of loop and that a variable could periodically be checked.
However, this is not the case. So something that won't necessarily be clean and that will just stop the execution whereever it is is acceptable.
You should take a look at these classes :
FutureTask, Callable, Executors
Here is an example :
public class TimeoutExample {
public static Object myMethod() {
// does your thing and taking a long time to execute
return someResult;
}
public static void main(final String[] args) {
Callable<Object> callable = new Callable<Object>() {
public Object call() throws Exception {
return myMethod();
}
};
ExecutorService executorService = Executors.newCachedThreadPool();
Future<Object> task = executorService.submit(callable);
try {
// ok, wait for 30 seconds max
Object result = task.get(30, TimeUnit.SECONDS);
System.out.println("Finished with result: " + result);
} catch (ExecutionException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
System.out.println("timeout...");
} catch (InterruptedException e) {
System.out.println("interrupted");
}
}
}
Java's interruption mechanism is intended for this kind of scenario. If the method that you wish to abort is executing a loop, just have it check the thread's interrupted status on every iteration. If it's interrupted, throw an InterruptedException.
Then, when you want to abort, you just have to invoke interrupt on the appropriate thread.
Alternatively, you can use the approach Sun suggest as an alternative to the deprecated stop method. This doesn't involve throwing any exceptions, the method would just return normally.
I'm assuming the use of multiple threads in the following statements.
I've done some reading in this area and most authors say that it's a bad idea to kill another thread.
If the function that you want to kill can be designed to periodically check a variable or synchronization primitive, and then terminate cleanly if that variable or synchronization primitive is set, that would be pretty clean. Then some sort of monitor thread can sleep for a number of milliseconds and then set the variable or synchronization primitive.
Really, you can't... The only way to do it is to either use thread.stop, agree on a 'cooperative' method (e.g. occassionally check for Thread.isInterrupted or call a method which throws an InterruptedException, e.g. Thread.sleep()), or somehow invoke the method in another JVM entirely.
For certain kinds of tests, calling stop() is okay, but it will probably damage the state of your test suite, so you'll have to relaunch the JVM after each call to stop() if you want to avoid interaction effects.
For a good description of how to implement the cooperative approach, check out Sun's FAQ on the deprecated Thread methods.
For an example of this approach in real life, Eclipse RCP's Job API's 'IProgressMonitor' object allows some management service to signal sub-processes (via the 'cancel' method) that they should stop. Of course, that relies on the methods to actually check the isCancelled method regularly, which they often fail to do.
A hybrid approach might be to ask the thread nicely with interrupt, then insist a couple of seconds later with stop. Again, you shouldn't use stop in production code, but it might be fine in this case, esp. if you exit the JVM soon after.
To test this approach, I wrote a simple harness, which takes a runnable and tries to execute it. Feel free to comment/edit.
public void testStop(Runnable r) {
Thread t = new Thread(r);
t.start();
try {
t.join(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (!t.isAlive()) {
System.err.println("Finished on time.");
return;
}
try {
t.interrupt();
t.join(2000);
if (!t.isAlive()) {
System.err.println("cooperative stop");
return;
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.err.println("non-cooperative stop");
StackTraceElement[] trace = Thread.getAllStackTraces().get(t);
if (null != trace) {
Throwable temp = new Throwable();
temp.setStackTrace(trace);
temp.printStackTrace();
}
t.stop();
System.err.println("stopped non-cooperative thread");
}
To test it, I wrote two competing infinite loops, one cooperative, and one that never checks its thread's interrupted bit.
public void cooperative() {
try {
for (;;) {
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.err.println("cooperative() interrupted");
} finally {
System.err.println("cooperative() finally");
}
}
public void noncooperative() {
try {
for (;;) {
Thread.yield();
}
} finally {
System.err.println("noncooperative() finally");
}
}
Finally, I wrote the tests (JUnit 4) to exercise them:
#Test
public void testStopCooperative() {
testStop(new Runnable() {
#Override
public void run() {
cooperative();
}
});
}
#Test
public void testStopNoncooperative() {
testStop(new Runnable() {
#Override
public void run() {
noncooperative();
}
});
}
I had never used Thread.stop() before, so I was unaware of its operation. It works by throwing a ThreadDeath object from whereever the target thread is currently running. This extends Error. So, while it doesn't always work cleanly, it will usually leave simple programs with a fairly reasonable program state. For example, any finally blocks are called. If you wanted to be a real jerk, you could catch ThreadDeath (or Error), and keep running, anyway!
If nothing else, this really makes me wish more code followed the IProgressMonitor approach - adding another parameter to methods that might take a while, and encouraging the implementor of the method to occasionally poll the Monitor object to see if the user wants the system to give up. I'll try to follow this pattern in the future, especially methods that might be interactive. Of course, you don't necessarily know in advance which methods will be used this way, but that is what Profilers are for, I guess.
As for the 'start another JVM entirely' method, that will take more work. I don't know if anyone has written a delegating class loader, or if one is included in the JVM, but that would be required for this approach.
Nobody answered it directly, so here's the closest thing i can give you in a short amount of psuedo code:
wrap the method in a runnable/callable. The method itself is going to have to check for interrupted status if you want it to stop (for example, if this method is a loop, inside the loop check for Thread.currentThread().isInterrupted and if so, stop the loop (don't check on every iteration though, or you'll just slow stuff down.
in the wrapping method, use thread.join(timeout) to wait the time you want to let the method run. or, inside a loop there, call join repeatedly with a smaller timeout if you need to do other things while waiting. if the method doesn't finish, after joining, use the above recommendations for aborting fast/clean.
so code wise, old code:
void myMethod()
{
methodTakingAllTheTime();
}
new code:
void myMethod()
{
Thread t = new Thread(new Runnable()
{
public void run()
{
methodTakingAllTheTime(); // modify the internals of this method to check for interruption
}
});
t.join(5000); // 5 seconds
t.interrupt();
}
but again, for this to work well, you'll still have to modify methodTakingAllTheTime or that thread will just continue to run after you've called interrupt.
The correct answer is, I believe, to create a Runnable to execute the sub-program, and run this in a separate Thread. THe Runnable may be a FutureTask, which you can run with a timeout ("get" method). If it times out, you'll get a TimeoutException, in which I suggest you
call thread.interrupt() to attempt to end it in a semi-cooperative manner (many library calls seem to be sensitive to this, so it will probably work)
wait a little (Thread.sleep(300))
and then, if the thread is still active (thread.isActive()), call thread.stop(). This is a deprecated method, but apparently the only game in town short of running a separate process with all that this entails.
In my application, where I run untrusted, uncooperative code written by my beginner students, I do the above, ensuring that the killed thread never has (write) access to any objects that survive its death. This includes the object that houses the called method, which is discarded if a timeout occurs. (I tell my students to avoid timeouts, because their agent will be disqualified.) I am unsure about memory leaks...
I distinguish between long runtimes (method terminates) and hard timeouts - the hard timeouts are longer and meant to catch the case when code does not terminate at all, as opposed to being slow.
From my research, Java does not seem to have a non-deprecated provision for running non-cooperative code, which, in a way, is a gaping hole in the security model. Either I can run foreign code and control the permissions it has (SecurityManager), or I cannot run foreign code, because it might end up taking up a whole CPU with no non-deprecated means to stop it.
double x = 2.0;
while(true) {x = x*x}; // do not terminate
System.out.print(x); // prevent optimization
I can think of a not so great way to do this. If you can detect when it is taking too much time, you can have the method check for a boolean in every step. Have the program change the value of the boolean tooMuchTime to true if it is taking too much time (I can't help with this). Then use something like this:
Method(){
//task1
if (tooMuchTime == true) return;
//task2
if (tooMuchTime == true) return;
//task3
if (tooMuchTime == true) return;
//task4
if (tooMuchTime == true) return;
//task5
if (tooMuchTime == true) return;
//final task
}