簡體   English   中英

如何通過線程訪問可運行對象?

[英]How to access a Runnable object by Thread?

可能重復: 需要幫助在線程運行方法中返回對象

你好。 我有一個實現runnable的類,還有一個List,用於存儲用該類的不同對象實例化的線程。 給定運行線程對象的基礎對象,如何訪問它們的屬性? 這是一個例子:

public class SO {
    public static class TestRunnable implements Runnable {
        public String foo = "hello";

        public void run() {
            foo = "world";
        }
    }

    public static void main(String[] args) {
        Thread t = new Thread(new TestRunnable());
        t.start();
        //How can I get the value of `foo` here?
    }
}

我在java.lang.Thread文檔中看不到任何方法。

那么,我最好的答案是您可能應該使用List<Runnable>而不是List<Thread> (或除了List<Thread>之外)。 或者,也許您想要某種映射結構,以便可以從線程訪問Runnable。 (例如, java.util.HashMap<java.lang.Thread, java.lang.Runnable>

並發庫很好地支持了這一點。 注意:如果您的任務拋出異常,則當您調用get()時,Future將保留此異常並引發包裝異常。

ExecutorService executor = Executors.newSingleThreadedExecutor();

Future<String> future = executor.submit(new Callable<String>() { 
   public String call() { 
      return "world"; 
   } 
}); 

String result = future.get(); 
TestRunnable r = new TestRunnable();
Thread t = new Thread(r);
t.start();
//there you need to wait until thread is finished, or just a simple Thread.sleep(1000); at this case
System.out.println(r.foo);

順便說一句,在實際情況下,您需要使用CallableFutureTask

如果要返回異步計算的值,請查看Callable和FutureTask:

FutureTask<String> task = new FutureTask(new Callable<String>() {
   public String call() {
      return "world";
   }
});
new Thread(task).start();
String result = task.get();

我認為通常您可以/應該避免這樣做,但是如果您確實需要這樣做,則不應該像MatrixFrog的建議工作(未經測試)那樣:

class RunnableReferencingThread extends Thread {
    public final Runnable runnable;
    public RunnableReferencingThread(Runnable r) {
        super(r);
        this.runnable = r;
    }
}

如果您的線程具有狀態信息,請忘記Runnable並簡單地擴展Thread,從而覆蓋run方法。

我有同樣的問題。 這是我的解決方案:

public static class TestRunnable implements Runnable {
    public String foo = "hello";

    public void run() {
        foo = "world";
    }

public static void main(String[] args) {
    TestRunnable runobject = new TestRunnable();
    Thread t = new Thread(runobject);
    runobject.foo;  //The variable from runnable. hello;
    t.start();
    runobject.foo;  //The variable from runnable. world;
}

這是您可以直接實現此方法的方式。

public static void main(String[] args) {
    // Keep a reference to the runnable object for later ...
    TestRunnable r = new TestRunnable();
    Thread t = new Thread(r);
    t.start();
    // Wait until the child thread has finished
    t.join();
    // Pull the result out of the runnable.
    System.out.println(r.foo);
}

但是,執行此類操作的現代方法(不太容易出錯)是使用java.util.concurrent的更高級別的並發類。

舉一個保羅·克勞利解決方案的具體例子,我認為這是他的建議:

public class BackgroundJob<JOB extends Runnable> extends Thread {

    private final JOB mJob;

    public BackgroundJob(JOB job) {
        super(job);
        mJob = job;
    }

    public JOB getJob() {
        return mJob;
    }

}

您可以繼承Thread的子類,並添加所需的方法。 由於一些令人討厭的Thread實現細節,您必須保留自己的目標Runnable副本,並覆蓋用於創建Thread的所有Thread構造函數。

我認為,如果可以的話,那就是恢復局勢。 那么在這種情況下,一個好的解決方案是將線程存儲在您的可運行類中。 而且您的runnable具有start()函數,該函數將啟動並自行啟動本地線程並調用thread.start。 這樣,您可以擁有線程對象的列表。 您也可以使用訪問器來獲取線程。

public class Threaded extends other implements Runnable {
    Thread localThread;

    @Override
    public void run() {
        //...
    }

    public void start() {
        localThread = new Thread(this);
        localThread.start();
    }

}

暫無
暫無

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

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