首页 文章

如何通过线程访问Runnable对象?

提问于
浏览
20

可能重复:need-help-returning-object-in-thread-run-method

你好 . 我有一个实现runnable的类,我有一个List,存储用该类的不同对象实例化的Threads . 在线程对象运行它们的情况下,如何访问底层对象的属性?这是一个例子:

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?
    }
}

11 回答

  • 1

    如果您的线程有状态信息,请忘记Runnable并简单地扩展Thread,覆盖run方法 .

  • 0

    并发库很好地支持了这一点 . 注意:如果您的任务抛出异常,则Future将保持此状态并在调用get()时抛出包装异常

    ExecutorService executor = Executors.newSingleThreadedExecutor();
    
    Future<String> future = executor.submit(new Callable<String>() { 
       public String call() { 
          return "world"; 
       } 
    }); 
    
    String result = future.get();
    
  • 12

    我在java.lang.Thread docs中没有看到任何方法 .

    那么,我最好的答案是你可能应该使用 List<Runnable> 而不是(或者除了) List<Thread> . 或者您可能需要某种map结构,以便您可以从线程访问Runnable . (例如, java.util.HashMap<java.lang.Thread, java.lang.Runnable>

  • 1

    我想,如果可以的话,就是要恢复局面 . 那么在这种情况下,一个好的解决方案是将线程存储在runnable类中 . 并且你的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();
        }
    
    }
    
  • 4

    如果要返回异步计算的值,请查看Callable和FutureTask:

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

    我有同样的问题 . 这是我的解决方案:

    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;
    }
    
  • 4

    这是你如何直接实现这一点 .

    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 中的更高级别的并发类 .

  • 10

    为了给出保罗克劳利解决方案的具体例子,我认为这是他的建议:

    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;
        }
    
    }
    
  • 2
    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);
    

    BTW,在实际情况下你需要使用 CallableFutureTask

  • 2

    我认为一般情况下你可以/应该避免这样做,但如果你真的需要这样做,不应该像MatrixFrog的建议工作(未经测试):

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

  • 0

    您可以继承Thread,并添加您需要的方法 . 您必须保留自己的目标Runnable副本并覆盖用于创建Thread的所有Thread构造函数,因为Thread的一些恼人的实现细节 .

相关问题