2013-07-19 2 views
6

Я пытаюсь получить доступ и изменить переменную потока в другом потоке в java, и я действительно не знаю, как это сделать.Доступ к переменной потока из другого потока в java

например:

Runnable r1 = new Runnable() { 
    int value = 10; 
    public void run() { 
     // random stuff 
    } 
} 
Runnable r2 = new Runnable() { 
    public void run() { 
     // of course the bellow line will not work 
     r1.value--; // I want here to be able to decrement the variable "value" of r1 
    } 
} 
Thread t1 = new Thread(r1); 
Thread t2 = new Thread(r2); 
t1.start(); 
t2.start(); 

спасибо, если у вас есть какая-либо идея!

Есть ли способ создать геттер и сеттер для потока в java?

EDIT: ответы были хорошие, но я не ясно, на мой вопрос, я попытаюсь задать вопрос лучше

+0

Нити не имеют переменных. Классы имеют члены, а методы имеют параметры и локальные переменные. Если вы переанализируете свою проблему в этом направлении, ответ должен быть очевиден. – EJP

ответ

4

Вы можете сделать это, но я предлагаю вам использовать AtomicInteger, который разделяет между потоками.

final AtomicInteger value = new AtomicInteger(10); 
Runnable r1 = new Runnable() { 
    public void run() { 
     // random stuff using value 
    } 
} 
Runnable r2 = new Runnable() { 
    public void run() { 
     value.decrementAndGet(); 
    } 
} 

Вы можете использовать AtomicReference для ссылок на объекты.

4

Создание работоспособной, и использовать сеттеров и добытчиками вы определяете в указанных работоспособной.

public class MyRunnable implements Runnable{ 
    private volatile String myString; 
    public String setString(String value){this.myString = value;} 
    public String getString(){ 
     return myString; 
    } 
    public void run(){} 
} 

Здесь используется ключевое слово volatile. Ключевое слово volatile гарантирует, что эта строка изменится в одном потоке, чтобы все потоки увидели изменение. Если вместо этого я гарантирую, что единственный доступ к объекту String осуществляется через синхронизированный контекст, тогда ключевое слово volatile не требуется.

Чтобы продемонстрировать свою точку зрения, приведенный выше код и приведенный ниже код являются поточно-безопасными, но отличаются друг от друга, поскольку ни один из 2 потоков не может вводить setString и getString одновременно в примере ниже.

public class MyRunnable implements Runnable{ 
    private String myString; 
    public synchronized String setString(String value){this.myString = value;} 
    public synchronized String getString(){ 
     return myString; 
    } 
    public void run(){} 
} 

Нить действительно просто выполняет runnable. Вы могли бы использовать это так:

MyRunnable runnable = new MyRunnable(); 
Thread myThread = new Thread(runnable); 
myThread.start(); 
String myString = runnable.getString(); 

Использование атомарных значений для примитивов это хорошо, но если вы хотите, чтобы разделить более сложный объект, вы должны будете прочитать о threading and synchronization.

Например:

public class Stats{ 
    int iterations; 
    long runtime; 
    public Stats(){ 
     iterations = 0; 
     runtime=0; 
    } 
    public synchronized void setIterations(int value){this.iterations = value;} 
    public synchronized void setRuntime(long milliseconds){ 
     this.runtime = milliseconds; 
    } 
    public synchronized int getIterations(){ 
     return iterations; 
    } 
    public synchronized long getRuntime(){return runtime;} 
} 

public class StatRunnable implements Runnable{ 
    Stats stats; 
    boolean active; 
    public StatRunnable(){ 
     this.active=true; 
    } 
    public Stats getStats(){ 
     return stats; 
    } 
    long calculateRuntime(){return 0L;} 
    public void run(){ 
     while(active){ 
      //i'm synchronizing with stats to ensure no other thread alters values 
      //simultaneously. 
      synchronized(stats){ 
       stats.setIterations(stats.getIterations()+1); 
       stats.setRuntime(calculateRuntime()); 
      } 
     } 
    } 
} 

Этот код показывает пример синхронизации с не примитивными объектами через ключевое слово synchronized. Использование ключевого слова synchronized в определении метода блокирует класс, используя себя как объект синхронизации.

Последнее замечание, синхронизированное ключевое слово используется не только в определениях методов. Вы можете использовать его для синхронизации по экземплярам внутри методов, как это было сделано в методе run, в StatRunnable.

+0

Можете ли вы привести пример безопасным потоком? Это похоже на исходный код, но с установщиком/получателем, а также прямым доступом к полю. –

+0

Это потокобезопасно, поскольку ничего не трогает String :), но да, я напишу более сложный пример. –

+0

AFAIK вы заменили 'String myString = runnable.myString;' на 'String myString = runnable.getString();' что делает то же самое. –

Смежные вопросы