10

我正在尝试访问和修改java中另一个线程中的线程变量,我真的不知道该怎么做。

前任 :

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();

有没有办法为java中的线程创建getter和setter?

编辑:答案很好,但我的问题不清楚,我会尝试问一个更好的问题

4

2 回答 2

7

创建一个 runnable,并使用您在上述 runnable 中定义的 setter 和 getter。

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(){}
}

注意volatile关键字在这里使用。volatile 关键字确保如果此字符串在一个线程中发生更改,则所有线程都会看到更改。相反,如果我确保对 String 对象的唯一访问是通过同步上下文,那么 volatile 关键字就不是必需的。

为了证明我的观点,上面的代码和下面的代码都是线程安全的,但不同的是,在下面的示例中,没有 2 个线程可以setString同时进入getString

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(){}
}

一个线程实际上只是在执行一个可运行的。你可以这样使用它:

MyRunnable runnable = new MyRunnable();
Thread myThread = new Thread(runnable);
myThread.start();
String myString = runnable.getString();

对原语使用原子值很好,但是如果您想共享更复杂的对象,则必须阅读有关线程和同步的内容。

例如:

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());
            }
        }
    }
}

synchronized此代码显示了通过关键字与非原始对象同步的示例。在方法定义中使用 synchronized 关键字会锁定使用自身作为同步对象的类。

最后一点,同步关键字不仅仅用于方法定义。您可以使用它来同步方法中的实例,就像我runStatRunnable.

于 2013-07-19T22:13:44.970 回答
7

你可以让它工作,但我建议你使用线程之间共享的AtomicInteger 。

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();
    }
}

您可以使用 AtomicReference 来引用对象。

于 2013-07-19T22:14:22.097 回答