доступ к разделяемой переменной внутри класса Runnable - PullRequest
6 голосов
/ 22 августа 2011

Мне нужно определить разделяемую переменную в методе main () моего основного класса.Мне нужно два потока, чтобы иметь доступ к этой общей переменной.Я создаю потоки, реализуя интерфейс Runnable и реализуя абстрактный метод run () интерфейса.Как обратиться к общей переменной, определенной в методе main () класса Main, из метода run (), определенного в моем классе, который реализует интерфейс Runnable?Очевидно, что просто вызывать их по имени не работает - так как они появляются из области видимости моего класса Runnable.

EDIT - извинения, вот простой пример

public Class DoThread implements Runnable {

    public void run(){
        sharedVar += 1
    }


}

и в отдельном .classfile:

public Class Main {

    public static void main(String[] args) {
        int sharedVar = 0;

        Thread t1 = new Thread(new DoThread());
        Thread t2 = new Thread(new DoThread());

        t1.start();
        t2.start();

        t1.join();
        t2.join();

    }


}

поэтому я должен создать объект для хранения разделяемой переменной и затем передать этот объект обоим конструкторам DoThread () при создании потоков?Я иногда путаюсь, когда java проходит по ref или проходит по var, поэтому, если я сделаю это таким образом, изменения в разделяемую переменную t1 будут видны t2?

Ответы [ 4 ]

11 голосов
/ 22 августа 2011

Что ж, если вы объявите переменную local , вы не сможете ссылаться на нее нигде, кроме как в классах, созданных в этом методе.

Где вы реализуете Runnable? Если он принадлежит к тому же классу, вы можете либо сделать его переменной экземпляра, а main установить переменную для того же экземпляра, из которого вы создаете поток, или сделать его статической переменной. Если Runnable реализован в другом классе, то, когда вы создаете экземпляр этого класса, вы можете предоставить ему необходимые данные - не совсем ясно, что это означает в данный момент ... Как уже говорили другие, код будет полезно. (Например, должны ли потоки видеть изменения в исходных данных?)

Кроме того, многопоточность относительно продвинута, тогда как распространение данных между классами является относительно базовым. Если вы новичок в Java, я бы рекомендовал начать с более простых вещей, чем многопоточность.

РЕДАКТИРОВАТЬ: Для вашего примера вы должны использовать AtomicInteger, например:

import java.util.concurrent.atomic.AtomicInteger;

class DoThread implements Runnable {

    private final AtomicInteger counter;

    DoThread(AtomicInteger counter) {
        this.counter = counter;
    }

    public void run() {
        counter.incrementAndGet();
    }
}

public class Test {
    public static void main(String[] args) throws InterruptedException {
        AtomicInteger shared = new AtomicInteger(0);

        Thread t1 = new Thread(new DoThread(shared));
        Thread t2 = new Thread(new DoThread(shared));

        t1.start();
        t2.start();

        t1.join();
        t2.join();

        System.out.println(shared.get()); // Prints 2
    }
}
8 голосов
/ 22 августа 2011

Код был бы полезен.

Если вы используете анонимный класс, вы можете объявить переменные как final, и они будут доступны в анонимном классе.

public void main(String[] args) {
    final int myvar = 0;
    new Thread(new Runnable() {
        public void run() {
            System.out.println("myvar: "+myvar);
        }
    }).start();
}
2 голосов
/ 22 августа 2011

Вам необходимо передать ссылку на общее значение.Если он не является ссылкой, вам нужно изменить его на AtomicReference, AtomicInt и т. Д. Или массив значения, которым вы хотите поделиться.

0 голосов
/ 22 августа 2011

Это место, где PassByRef более эффективен.Передайте ссылку на переменную в оба запускаемых экземпляра.Это все ... с этого момента на него можно ссылаться внутри вашего метода run.

Пример:

Thread th1 = new Thread (Myrunnable (varRef)).Аналогично для другой темы

...