开发者

Is it possible to update an attribut within a thread

开发者 https://www.devze.com 2023-03-11 02:19 出处:网络
Let say that I create an object and run it in a thread, something like this. public class Main { public static void main(String[] args) {

Let say that I create an object and run it in a thread, something like this.

public class Main {

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

}}

Is it possible to update the parameter passed in SomeClass with a methode updateNumber() as fallows:

# Updated

class SomeClass extends Thread {
     volatile int number ;
     SomeClass (int number ) {
         this.number = number ;
     }

     public void run() {
         while(t开发者_运维问答rue){
          System.out.println(number);
           }
     }

  public  void updateNumber(int n){     
          number =n;
          }
  }   

Result : 144 144 144 144 144 ...

Thanks


Yes, but you need to declare number as volatile, or (preferably) use an AtomicLong instead of a long.


Declare number as volatile.

When is volatile needed ?

When multiple threads using the same variable, each thread will have its own copy of the local cache for that variable. So, when it's updating the value, it is actually updated in the local cache not in the main variable memory. The other thread which is using the same variable doesn't know anything about the values changed by the another thread. To avoid this problem, if you declare a variable as volatile, then it will not be stored in the local cache. Whenever thread are updating the values, it is updated to the main memory. So, other threads can access the updated value


One other option not mentioned and which is the option you should use instead of synchronization as mentioned above is the make use of the Concurrency package introduced by Doug Lee in Java 1.5.

Use the Atomic classes, these take care of all you concurrency woes. (well to a point)

Something like this:

 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

In my opinion the Java Concurrency in Practice is the best book on threading in Java


SomeClass even it is Runnable, it is just a normal class and objects of it can be accessed by any thread that has reference to it. In your example. you are not calling updateNumber() form anywhere, but if you call it after p.start(), you are acessing it from the thread that actually made the instance. If you are calling updateNumber() in run(), then you are accessing it from the thread you've just started.

The other question is: is it safe in your setup to change it form multiple threads? the answer is no. You have to declare it as volatile (let say), or synchronize if you changing it based on current value. How and what to synchronize depends on what you are actually doing with it.


You can use the keyword volatilewhen all the following criteria are met:

  • Writes to the variable do not depend on its current value, or you can ensure that only a single thread ever updates the value
  • The variable does not participate in invariants with other state variables
  • Locking is not required for any other reason while the variable is being accessed

Otherwise, I'd recommend using some sort of synchronization policy

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


Yes, you can just call p.updateNumber(...) but you will need to be careful of thread synchronization issues.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号