簡體   English   中英

從線程的方法調用未完成-如何結束線程-解決方法

[英]Method call from thread does not finish - How to end the thread - Workaround

我有以下代碼。

ReadWriteLock someLock = new ReentrantReadWriteLock();
Condition someCondition = someLock.writeLock().newCondition();

public someMethod() {
    // do some stuff
    someCondition.await(); //Lock here.
    System.out.prinltn("This never prints");
}

public doSomeStuff() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                someMethod();
                System.out.println("thread finished");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("thread is going to die");
        }
    }).start();
}

當線程調用方法someMethod()它將被執行。 但是由於該函數上有一個await()方法。 除非它被singnalAll()喚醒,否則它永遠不會結束/不會打印“這永遠不會打印”。 但是我希望線程一旦執行就可以完成。

我無法重構整個事情。 我只需要解決此問題的方法。 它在Swing應用程序中使用。 因此線程很重要。

我認為這可以做到:

Thread thread =
  new Thread(new Runnable() {
    @Override
    public void run() {
        try {
          someMethod();
          System.out.println("thread finished");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("thread is going to die");
    }
  });

thread.start( );

final long reasonableTimeout = ...;

thread.join( reasonableTimeout );

// THIS WILL SHAKE IT UP
thread.interrupt( );

thread.join( );

// At this point, it is guaranteed that the thread has finished

我不確定我是否正確理解了您的問題,但是我認為您想啟動someMethod()函數,然后使調用者退出而不等待someMethod()完成。 這意味着您基本上將執行流分為兩部分,一處是someMethod()正在運行,以等待其應有的喚醒,另一處是調用方在調用someMethod之后繼續進行(如果要完成,則需要執行此操作) ()。 為此,您將必須在單獨的線程中運行someMethod()。 這樣的事情。

public doSomeStuff() {
    new Thread(new Runnable() {
        @Override
        public void run() {
        try {
            new Thread(){
                public void run(){
                    someMethod();
                }
            }.start();
            System.out.println("thread finished");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("thread is going to die");
    }
  }).start();
}

有兩種方法可以解決此問題。

1)使用中斷策略設計任務

進行防御性編碼。 如果您的任務以任何方式中斷,程序應知道如何處理。

2)如本例所示 ,添加毒葯,

public someMethod() {
    while(condition predicate){
    someCondition.await(TIME_OUT); //Lock here.
}
//ADD Poison pill here
    System.out.prinltn("This never prints");
}    

根據實踐中的Java並發性

使用條件等待(Object.wait或Condition.await)時:

1)始終有一個條件謂語必須對對象狀態進行某種測試才能繼續進行;

2)總是在調用wait之前,以及從wait返回之后再次測試條件謂詞;

3)總是循環調用wait;

4)確保組成條件謂詞的狀態變量受到與條件隊列關聯的鎖的保護;

5)在調用wait,notify或notifyAll時,保持與條件隊列關聯的鎖;

6)在檢查條件謂詞之后但在對它進行操作之前,請勿釋放該鎖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM