Java - How to safely stop a thread in a web application from a GUI?

Is there a way to safely and immediately stop Thread execution in Java? In particular, if the logic inside the run()

implementation method onlyRunnable

does one iteration and does not regularly check any flag that tells it to stop?

I am creating a web application using which a user can translate the content of an entire document from one language to another.

Assuming the documents are very large and therefore each translation will take a long time (say 20-25 minutes), my application creates a separate thread for each translation initiated by its users. The user can see a list of active translations and decides to stop a specific translation job if he so desires.

This is my .java translator

public class Translator {
   public void translate(File file, String sourceLanguage, String targetLanguage) {
    //Translation happens here
    //.......
    //Translation ends and a new File is created.
   }

}

      

I created a class TranslatorRunnable

that implements the interface Runnable

as follows:

public class TranslatorRunnable implements Runnable {

    private File document;
    private String sourceLanguage;
    private String targetLanguage;

    public TranslatorRunnable(File document, String sourceLanguage, String targetLanguage) {
        this.document = document;
        this.sourceLanguage = sourceLanguage;
        this.targetLanguage = targetLanguage;
    }

    public void run() {
        // TODO Auto-generated method stub
        Translator translator = new Translator();
        translator.translate(this.document, this.sourceLanguage, this.targetLanguage);
        System.out.println("Translator thread is finished.");
    }

}

      

I am creating a stream to translate a document from an external class like this:

TranslatorRunnable tRunnable = new TranslatorRunnable(document, "ENGLISH", "FRENCH");
Thread t = new Thread(tRunnable);
t.start();

      

Now my problem is how to stop the translation process (essentially a thread) when the user clicks "Stop" in the GUI?

I read several posts on StackOverflow as well as other sites that say I have a flag volatile boolean

inside the implementation Runnable

that I have to check regularly from the method run()

and decide when to stop. See this post

This doesn't work for me, as the run () method just calls the Translator.translate () method, which itself will take a long time. I have no choice here.

The next thing I read was to use ExecutorService

and use his method shutDownAll()

. But even here I will have to process InterruptedException

somewhere regularly in my code. Again, this is not an option. Recalls that documentation ExecutorService class.

I know I cannot use Thread.stop()

as it is deprecated and can cause problems with objects that are commonly used by all threads.

What options do I have?

Is my requirement really doable without significant changes to my design? If so, please tell us.

If I absolutely need to redesign, can someone tell me what is the best approach I can take?

Thanks, Sriram

+3


source to share


2 answers


Is there a way to safely and immediately stop Thread execution in Java?

Not. each thread is responsible for checking periodically if it was interrupted to exit as soon as possible



if (Thread.currentThread().isInterrupted() ) {
  // release resources. finish quickly what it was doing
}

      

if you want a more responsive application, you need to change the logic (for example, divide each job into smaller batches) so that each thread performs this check more often than every 20-25 minutes.

+2


source


If you created the Translator class, which prevents you from adding some value inside a function that is periodically checked and, if necessary, stops reading lines from the file, something like this



   public static List<String> readFile(String filename)
{
    List<String> records = new ArrayList<>();
    try
    {
        BufferedReader reader = new BufferedReader(new FileReader(filename));
        String line;
        while ((line = reader.readLine()) != null)
        {
            String[] split = line.split("\\s+");
            records.addAll(Arrays.asList(split));
            if (needsToStop) {
                break; //Or throw exception
            }
        }
        reader.close();
        return records;
    }
    catch (Exception e)
    {
        System.err.format("Exception occurred trying to read '%s'.", filename);
        e.printStackTrace();
        return null;
    }
}

      

0


source







All Articles