我有以下代码,但是当我在新的Thread类之外声明String行时,我得到一个异常。我来自C#背景,所以我现在明白Java不支持真正的闭包。所以我的问题是:
如何在新线程之外声明一个字符串并在新线程中使用它?
不能引用定义的内部类中的非final变量行 用另一种方法
ProcessBuilder builder =
new ProcessBuilder("/Users/Joe/Desktop/file", "-i", src);
builder.redirectErrorStream(true);
Process process = builder.start();
final InputStream is = process.getInputStream();
String line;
new Thread(new Runnable() {
@Override public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while ((br.readLine()) != null) {
line += br.readLine() + "\n";
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
答案 0 :(得分:3)
将line
更改为StringBuilder
并将其声明为final
。然后更改run()
方法以附加到StringBuilder
。
如果您在尝试阅读主线程中的join()
之前line
子线程,则无需使用StringBuffer
。
答案 1 :(得分:1)
你必须:
以下是代码示例:
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class FutureJob {
static class StreamToString implements Callable< String > {
BufferedReader br;
public StreamToString( InputStream in ) {
br = new BufferedReader( new InputStreamReader( in ));
}
@Override public String call() throws Exception {
StringBuilder buffer = new StringBuilder( 1024 );
String line;
while(( line = br.readLine()) != null ) {
buffer.append( line );
buffer.append( '\n' );
}
br.close();
return buffer.toString();
}
}
public static void main( String[] args ) throws Exception {
ProcessBuilder builder = new ProcessBuilder( "cmd", "/C", "dir", "c:\\" );
Process process = builder.start();
ExecutorService executor = Executors.newSingleThreadExecutor();
StreamToString toString = new StreamToString( process.getInputStream());
Future< String > result = executor.submit( toString );
System.out.println( result.get());
executor.shutdownNow();
}
}
如果需要,调用者的阻塞等待由result.get()
在内部进行。
答案 2 :(得分:0)
您应该创建另一个对象来保存和更改String
。将此对象设为final并使用此对象方法更改字符串。
您可以尝试使用StringBuilder
作为最终对象,并使用其append
函数来修改字符串。
答案 3 :(得分:0)
或者,将line
声明为内部类中的实例变量,因为您还没有在类之外使用它:
new Thread(new Runnable() {
String line;
@Override public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while ((br.readLine()) != null) {
line += br.readLine() + "\n";
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();