Можно ли обновить аттрибут в потоке? - PullRequest
0 голосов
/ 06 июня 2011

Допустим, я создаю объект и запускаю его в потоке, что-то вроде этого.

public class Main {

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

}}

Возможно ли обновить параметр, переданный в SomeClass, с помощью метода updateNumber (), как пары:

# Обновлено

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 ]

2 голосов
/ 06 июня 2011

Объявите число как volatile.

Когда требуется летучий?

Когда несколько потоков используют один и тот же переменная, каждый поток будет иметь собственная копия локального кэша для этого переменная. Итак, когда он обновляет значение, оно на самом деле обновляется в локальный кеш не в основной переменной объем памяти. Другой поток, который использование той же переменной не знает что-нибудь о значениях, измененных другая нить. Чтобы избежать этого проблема, если вы объявите переменную как volatile , тогда оно не будет сохранено в локальном кеше. Всякий раз, когда нить обновляются значения, обновляется в основную память. Итак, другие темы может получить доступ к обновленному значению

2 голосов
/ 06 июня 2011

Да, но вам нужно объявить number как volatile или ( предпочтительно ) использовать AtomicLong вместо long.

1 голос
/ 06 июня 2011

Еще одна опция, не упомянутая и которая должна использоваться вместо синхронизации, как упомянуто выше, - это использование пакета Concurrency, представленного Дугом Ли в Java 1.5.

Используйте классы 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 на практике

По моему мнению, Java Concurrency на практике - лучшая книга по многопоточности в Java

1 голос
/ 06 июня 2011

Вы можете использовать ключевое слово 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();
      }
  }
}
1 голос
/ 06 июня 2011

SomeClass, даже если он является Runnable, это просто обычный класс, и к объектам этого может обращаться любой поток, имеющий ссылку на него . В вашем примере. вы нигде не вызываете updateNumber() форму, но если вы вызываете ее после p.start (), вы обращаетесь к ней из потока, который фактически создал экземпляр. Если вы звоните updateNumber() в run(), то вы обращаетесь к нему из только что начатой ​​цепочки.

Другой вопрос: безопасно ли в вашей настройке изменять его из нескольких потоков? ответ - нет. Вы должны объявить его как volatile (скажем,) или synchronize, если вы меняете его на основе текущего значения. Как и что синхронизировать, зависит от того, что вы на самом деле делаете с ним.

0 голосов
/ 06 июня 2011

Да, вы можете просто позвонить p.updateNumber(...), но вам нужно быть осторожным с проблемами синхронизации потоков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...