问题
I'm trying to access and modify a variable of a thread in another thread in java, and I really don't know how to do this.
ex :
Runnable r1 = new Runnable() {
int value = 10;
public void run() {
// random stuff
}
}
Runnable r2 = new Runnable() {
public void run() {
// of course the bellow line will not work
r1.value--; // I want here to be able to decrement the variable "value" of r1
}
}
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
thank you if you have any idea!
Is there any way to create a getter and setter for a thread in java?
EDIT : the answers were good, but I was not clear in my question, I will try asking a better question
回答1:
You could make it sort of work but, I suggest you use an AtomicInteger which is shared between threads.
final AtomicInteger value = new AtomicInteger(10);
Runnable r1 = new Runnable() {
public void run() {
// random stuff using value
}
}
Runnable r2 = new Runnable() {
public void run() {
value.decrementAndGet();
}
}
You can use AtomicReference for references to objects.
回答2:
Create a runnable, and use the setters and getters you define in said runnable.
public class MyRunnable implements Runnable{
private volatile String myString;
public String setString(String value){this.myString = value;}
public String getString(){
return myString;
}
public void run(){}
}
Note volatile
keyword is used here. The volatile keyword ensures if this String changes in one thread, that all threads will see the change. If instead I ensure that the only access to the String object is through synchronized context, then the volatile keyword would not be necessary.
To demonstrate my point, the above code and the below code are both thread-safe but are different as no 2 threads can enter setString
and getString
simultaneously in the example below.
public class MyRunnable implements Runnable{
private String myString;
public synchronized String setString(String value){this.myString = value;}
public synchronized String getString(){
return myString;
}
public void run(){}
}
A thread is really just executing a runnable. You could use this like so:
MyRunnable runnable = new MyRunnable();
Thread myThread = new Thread(runnable);
myThread.start();
String myString = runnable.getString();
Using atomic values for primitives is fine, but if you ever want to share a more complex object, you'll have to read about threading and synchronization.
For example:
public class Stats{
int iterations;
long runtime;
public Stats(){
iterations = 0;
runtime=0;
}
public synchronized void setIterations(int value){this.iterations = value;}
public synchronized void setRuntime(long milliseconds){
this.runtime = milliseconds;
}
public synchronized int getIterations(){
return iterations;
}
public synchronized long getRuntime(){return runtime;}
}
public class StatRunnable implements Runnable{
Stats stats;
boolean active;
public StatRunnable(){
this.active=true;
}
public Stats getStats(){
return stats;
}
long calculateRuntime(){return 0L;}
public void run(){
while(active){
//i'm synchronizing with stats to ensure no other thread alters values
//simultaneously.
synchronized(stats){
stats.setIterations(stats.getIterations()+1);
stats.setRuntime(calculateRuntime());
}
}
}
}
This code shows an example of synchronization with non-primitive objects via the synchronized
keyword. Using the synchronized keyword in a method definition locks the class using itself as the synchronizing object.
A final note, the synchronized keyword isn't just used in method definitions. You can use it to synchronize on instances within methods as I've done in the run
method in StatRunnable
.
来源:https://stackoverflow.com/questions/17756255/accessing-a-variable-of-a-thread-from-another-thread-in-java