假设我创建了一个对象并在一个线程中运行它,就像这样。
public class Main {
public static void main(String[] args) {
SomeClass p = new SomeClass (143);
p.start();
p.updateNumber(144);
}}
是否可以使用methode updateNumber()更新在SomeClass中传递的参数作为fallows:
#Updated
class SomeClass extends Thread {
volatile int number ;
SomeClass (int number ) {
this.number = number ;
}
public void run() {
while(true){
System.out.println(number);
}
}
public void updateNumber(int n){
number =n;
}
}
结果: 144 144 144 144 144 ...
由于
答案 0 :(得分:2)
是的,但您需要将number
声明为volatile
,或者preferably)使用AtomicLong
而不是long
。
答案 1 :(得分:2)
将数字声明为volatile
。
什么时候需要挥发性?
当多个线程使用相同时 变量,每个线程都会有它的 拥有本地缓存的副本 变量。所以,当它正在更新时 值,它实际上是在更新 本地缓存不在主变量中 记忆。另一个线程是 使用相同的变量不知道 关于价值的任何改变 另一个线程。为了避免这种情况 问题,如果你声明一个变量 易失性,然后就不会存储 在本地缓存中。每当线程 正在更新值,它会更新 到主存。所以,其他线程 可以访问更新的值
答案 2 :(得分:1)
SomeClass
即使它是Runnable,它只是一个普通的类,它的对象可以被任何引用它的线程访问。在你的例子中。你没有在任何地方调用updateNumber()
表单,但如果你在p.start()之后调用它,你就可以从实际创建实例的线程中获取它。如果您在updateNumber()
中呼叫run()
,那么您将从刚刚开始的主题中访问它。
另一个问题是:在您的设置中从多个线程更改它是否安全?答案是不。如果您根据当前值更改它,则必须将其声明为volatile
(比方说)或synchronize
。 如何以及要同步的内容取决于您实际使用它的方式。
答案 3 :(得分:1)
满足以下所有条件时,您可以使用关键字volatile
:
否则,我建议使用某种同步策略
class SomeClass implements Runnable {
private Integer number;
SomeClass (int number) {
this.number = Integer.valueOf(number);
}
@Override
public void run() {
while(true){
System.out.println(getNumber());
}
}
public void updateNumber(int n){
synchronized(number){
number = Integer.valueOf(n);
}
}
public int getNumber(){
synchronized(number){
return number.intValue();
}
}
}
答案 4 :(得分:1)
未提及的另一个选项是,如上所述,您应该使用的选项而不是同步是使用Doug Lee在Java 1.5中引入的Concurrency包。
使用Atomic类,这些可以解决所有并发问题。 (好到一点)
这样的事情:
private AtomicInteger number = new AtomicInteger(0);
public void updateNumber(int n) {
number.getAndSet(n);
}
public int getNumber() {
return number.get();
}
Java 1.6 AtomicInteger JavaDoc
在我看来,Java Concurrency in Practice是关于Java中线程的最佳书籍
答案 5 :(得分:0)
是的,你可以只调用p.updateNumber(...)
但是你需要注意线程同步问题。