[英]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);
順便說一句,在實際情況下,您需要使用Callable
和FutureTask
如果要返回異步計算的值,請查看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.