从java中的另一个线程访问一个线程的变量
Posted
技术标签:
【中文标题】从java中的另一个线程访问一个线程的变量【英文标题】:Accessing a variable of a thread from another thread in java 【发布时间】:2013-07-19 08:08:28 【问题描述】:我正在尝试访问和修改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?
编辑:答案很好,但我的问题不清楚,我会尝试问一个更好的问题
【问题讨论】:
线程没有变量。类有成员,方法有参数和局部变量。如果您按照这些思路重新分析您的问题,答案应该是显而易见的。 【参考方案1】:创建一个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 关键字就没有必要了。
为了证明我的观点,上面的代码和下面的代码都是线程安全的,但不同的是,在下面的例子中没有两个线程可以同时输入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()
一个线程实际上只是在执行一个runnable。你可以这样使用:
MyRunnable runnable = new MyRunnable();
Thread myThread = new Thread(runnable);
myThread.start();
String myString = runnable.getString();
对原语使用原子值很好,但如果您想共享更复杂的对象,则必须阅读threading and synchronization.
例如:
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 关键字会锁定使用自己作为同步对象的类。
最后一点,同步关键字不仅仅用于方法定义。您可以使用它来同步方法中的实例,就像我在 StatRunnable
中的 run
方法中所做的那样。
【讨论】:
你能提供一个线程安全的例子吗?这看起来像原始代码,但具有 setter/getter 以及对字段的直接访问。 这是线程安全的,因为没有任何东西触及字符串 :) 但是是的,我会写一个更复杂的例子。 AFAIK 你已经用String myString = runnable.getString();
替换了String myString = runnable.myString;
,它做同样的事情。
我知道,迟到几年总比没有好,但您的解决方案效果很好。谢谢!
@kpont 很高兴听到这个消息!希望它在线程方面对您有所帮助,这是一个复杂的主题。【参考方案2】:
你可以让它工作,但我建议你使用线程之间共享的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 来引用对象。
【讨论】:
以上是关于从java中的另一个线程访问一个线程的变量的主要内容,如果未能解决你的问题,请参考以下文章