是否可以更新线程中的属性

时间:2011-06-06 01:32:59

标签: java multithreading runnable

假设我创建了一个对象并在一个线程中运行它,就像这样。

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 ...

由于

6 个答案:

答案 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 Concurrency in Practice是关于Java中线程的最佳书籍

答案 5 :(得分:0)

是的,你可以只调用p.updateNumber(...)但是你需要注意线程同步问题。