Reputation: 2045
I have the following code:
public class Shell {
String status;
Runtime rtime;
Process process;
public void runCmd(final String cmd,String status) throws Exception{
this.status = status;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
process = rtime.exec(cmd);
process.waitFor();
this.status = "check out done";
} catch (IOException e) {
} catch (InterruptedException e) {
}
}
});
t.start();
}
}
but java doesn't let me change the status
variable inside the new thread t.May be I need some sort of inter thread communication.I am new to threads,please tell me how to do this.
Upvotes: 2
Views: 514
Reputation: 65813
The problem is that you cannot access a variable from a parent class in an anonymous class unless it is final and even then it is complex. As you want to modify it I would suggest something like:
public class Holder <T> {
private T held = null;
public Holder () {
}
public Holder (T it) {
held = it;
}
public void hold(T it) {
held = it;
}
public T held() {
return held;
}
@Override
public String toString () {
return held == null ? "null": held.toString();
}
}
Then your code can look like this:
public class Shell {
final Holder<String> status = new Holder<>();
Runtime rtime;
Process process;
public void runCmd(final String cmd, String status) throws Exception {
// Set the status.
Shell.this.status.hold(status);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
process = rtime.exec(cmd);
process.waitFor();
Shell.this.status.hold("check out done");
} catch ( IOException | InterruptedException e) {
}
}
});
t.start();
}
}
Added
This demopnstration of the use of a Holder
is the solution to a different problem - i.e. the need to modify a final object from inside an anonymous class.
This answer is not the solution to OP's problem and I would delete it if I could. Unfortunately it has been marked as the answer so I cannot.
If OP could mark one of the other posts as the correct answer I would be happy to delete this.
Upvotes: 1
Reputation: 41935
public class Shell {
volatile String status;
public void runCmd(final String cmd) throws Exception{
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Process process = Runtime.getRuntime().exec(cmd);
process.waitFor();
Shell.this.status = "check out done";
} catch (IOException e) {
} catch (InterruptedException e) {
}
}
});
t.start();
t.join();
System.out.println(status);
}
}
Use Shell.this.status
and update the value to what to want.
Always use volatile
when reference is updated from another thread.
Upvotes: 1
Reputation: 968
In your case this
in expression this.status
refers Runnable object which does not have status field defined. Try Shell.this.status
instead of this.status
.
Upvotes: 3