2017-06-14 97 views
3

有沒有辦法在Java中安全且立即停止執行Thread?尤其是,如果方法的run()方法中的邏輯執行只有一次迭代,並且不定期檢查任何標誌,告訴它停止?Java - 如何從GUI中安全地停止Web應用程序中的線程?

我正在構建一個Web應用程序,使用它可以將整個文檔的內容從一種語言翻譯成另一種語言。

假設文檔非常大,隨後假定每個翻譯都需要很長時間(比如20-25分鐘),我的應用程序會爲每個由用戶發起的翻譯創建一個單獨的線程。用戶可以看到活動翻譯列表,並決定如果他/她希望停止特定的翻譯工作。

這是我Translator.java

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

} 

我創建了一個TranslatorRunnable類,如下所示它實現了Runnable接口:

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."); 
    } 

} 

我創建的線程從翻譯的文檔外部類如下:

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

Now我的問題是,當用戶點擊GUI中的「停止」時,如何停止翻譯過程(本質上是線程)?

我已閱讀StackOverflow上以及在其他網站上的幾個帖子,這告訴我有Runnable實現,這是我應該從run()方法內部定期檢查,並決定何時停止內部volatile boolean標誌。 See this post

這對我不起作用,因爲run()方法只是調用Translator.translate()方法,而該方法本身需要很長時間。我在這裏沒有選擇。

我讀的下一件事是使用ExecutorService並使用其shutDownAll()方法。但即使在這裏,我也必須在我的代碼中定期處理InterruptedException。這一點再次超出了選項。涉及ExecutorService類的this documentation

我知道我不能使用Thread.stop(),因爲它已被棄用,並可能導致所有線程通常使用的對象出現問題。

我有什麼選擇?

如果我的設計沒有實質性改變,我的要求是否真的可行?如果是,請告訴我如何。

如果對我來說改變設計是絕對必要的,誰能告訴我什麼是我能採取的最好的方法?

感謝, 斯利拉姆

+0

你可以使用t.interrupt() – Debu

回答

2

有沒有一種方法能夠安全,立即停止在Java線程的執行?

No.每個線程都是reponsible定期檢查它是否已被中斷,如果你想要一個更敏感的應用,以儘快

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

退出,你必須改變的邏輯(例如劃分在小批量每個作業),因此每個線程檢查的次數比每20-25分鐘更頻繁

0

如果您是創建Translator類的人,那麼阻止您在定期檢查的函數內添加某種類型的值,並且如果需要,可以停止讀取行從文件這樣的事情

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

這不是那麼簡單,因爲translate()方法又調用了許多其他的類,方法和庫,每個類可能加起來就是整個執行時間。因此,如果我希望我的應用程序在用戶單擊停止按鈕時作出響應,我無法做到這一點。 – sriramsridharan

+0

是否有任何部分代碼需要很長時間,並且您無法控制它或者是您控制的所有內容? – urag

+0

translate()方法反過來調用一個執行大部分任務的庫,並且我無法控制它。除了調用這些庫之外,我在translate()方法中所做的所有操作都是更新翻譯狀態(這是唯一可以控制的地方) – sriramsridharan