2013-04-23 68 views
0

如何在java中为run()外部的字符串赋值。它开始新的线程,运行并获得价值,然后应该返回它。如果我尝试在线程中设置字符串=值,它告诉我我需要将字符串更改为最终哪个不会工作然后Java:从运行线程设置赋值给字符串?

对此的任何建议?

+1

虽然我不完全确定这是你需要的,但如果你想从一个单独的线程返回一个值,请查看Callable接口http://docs.oracle.com/javase/1.5.0/docs /api/java/util/concurrent/Callable.html并使用执行程序 – 2013-04-23 01:00:01

回答

0

正如Ron Dahlgren所评论的,正确的方法是使用Callable。做到这一点的黑客是您的字符串分配到的final String[] oneStringReference = new String[1];

public class MyCallable implements Callable { 
    private Object param1; 
    private Object param2; 
    private Object param3; 

    public MyCallable(Object param1, Object param2, Object param3) { 
     this.param1 = param1; 
     this.param2 = param2; 
     this.param3 = param3; 
    } 

    public Object Callable() { 
     ... 
    } 
} 
+0

我不会用数组引用“破解”它 - 没有外部“同步”声明,这不是线程安全的方式来传递数据,并且可能导致意想不到的行为! – 2013-04-23 01:27:56

+0

我得到它的工作谢谢,只是想以某种方式获取参数调用() – arleitiss 2013-04-23 02:08:30

+0

创建一个实现Callable的新类,并将您的参数传递给它的构造函数 – 2013-04-23 02:24:44

1

的第一要素“它告诉我,我需要字符串更改为最终这不会工作,那么”

似乎暗示我的问题不是关于线程,而是关联(匿名)内部类访问封闭范围中的变量。

我敢打赌,你在做什么是这样的:

class Foo { 
    public void foo() { 
     String myString = "abc"; 

     Thread t = new Thread(
      new Runnable() { 
       @Override 
       public void run() { 
        myString = "xyz"; 
       } 
      } 
     }; 
     t.start(); 
     t.join(); 
     System.out.println("result :" + myString); 
    } 
} 

你会发现编译器是抱怨的“myString的应该是最后的”类似的东西。它与多线程无关。对于匿名内部类而言,它只能访问封闭范围中的最终变量。

鉴于字符串是不可变的,通过保持原始代码结构来解决的方法之一是让一些字符串的持有者是最终的。字符串数组是一个可能的选择,或者你可以做一个支架这么简单:

public class StringHolder { 
    String value; 
    public StringHolder(String value) { 
     this.value = value; 
    } 
    public void setValue(String value) { 
     this.value = value; 
    } 
    public value getValue() { 
     return this.value; 
    } 
} 

和更改您的代码是这样的:

class Foo { 
    public void foo() { 
     String myString = "abc"; 
     final StringHolder myStringHolder = new StringHolder(myString); 

     Thread t = new Thread(
      new Runnable() { 
       @Override 
       public void run() { 
        myStringHolder.setValue("xyz"); 
       } 
      } 
     }; 
     t.start(); 
     t.join(); 
     System.out.println("result: " + myStringHolder.getValue()); 
    } 
} 

然而,这不是推荐的方式从线程获取结果。

我强烈建议您更改您的代码结构,并查看Future(以及相关类)的用法。