0

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

public class Main {

public static void main(String[] args) {
    SomeClass p = new SomeClass (143);
    p.start();
    p.updateNumber(144);

}}

是否可以使用方法 updateNumber() 更新 SomeClass 中传递的参数作为休闲方式:

# 更新

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

谢谢

4

6 回答 6

2

是的,但是您需要声明numbervolatile,或者(最好)使用 anAtomicLong而不是 a long

于 2011-06-06T01:37:23.830 回答
2

将数字声明为volatile

什么时候需要 volatile ?

当多个线程使用同一个变量时,每个线程都会为该变量拥有自己的本地缓存副本。因此,当它更新值时,它实际上是在本地缓存中更新,而不是在主变量内存中。使用相同变量的另一个线程对另一个线程更改的值一无所知。为了避免这个问题,如果你将一个变量声明为 volatile,那么它将不会被存储在本地缓存中。每当线程更新值时,它都会更新到主内存。因此,其他线程可以访问更新的值

于 2011-06-06T01:38:00.757 回答
1

SomeClass即使它是可运行的,它也只是一个普通的类,它的对象可以被任何引用它的线程访问。在你的例子中。你没有updateNumber()在任何地方调用表单,但是如果你在 p.start() 之后调用它,你正在从实际创建实例的线程中访问它。如果您正在调用updateNumber()in run(),那么您正在从刚刚启动的线程中访问它。

另一个问题是:在您的设置中从多个线程更改它是否安全?答案是不。您必须将其声明为volatile(比如说),或者synchronize如果您根据当前值更改它。同步的方式和内容取决于您实际使用它做什么。

于 2011-06-06T01:39:04.057 回答
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();
      }
  }
}
于 2011-06-06T01:59:02.690 回答
1

另一个没有提到的选项是使用 Doug Lee 在 Java 1.5 中引入的 Concurrency 包而不是上面提到的同步选项。

使用原子类,这些可以解决你所有的并发问题。(在一定程度上)

像这样的东西:

 private AtomicInteger number = new AtomicInteger(0);

 public void updateNumber(int n) {
   number.getAndSet(n);
 }

 public int getNumber() {
   return number.get();
 }

Java 1.6 原子整数 JavaDoc

Java 并发实践

在我看来,Java Concurrency in Practice 是关于 Java 线程的最好的书

于 2011-06-06T07:50:36.063 回答
0

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

于 2011-06-06T01:39:13.700 回答