Подсчет одной переменной в нескольких потоках - PullRequest
0 голосов
/ 06 апреля 2011

У меня есть следующий исполняемый класс.

public class OnesRun implements Runnable {

    public int ones = 0;

    private int passendNumber;

    public OnesRun(int passendNumber) {
        this.passendNumber = passendNumber;
    }

    public void run() {
        if (passendNumber == 1)
            ones++;
    }

}

Каждый экземпляр этого класса должен увеличивать значение ones, если встречает единицу.

После того, как все потоки были выполнены, я хочу прочитать значение ones вне класса.

  1. Как я могу увеличить ones потокобезопасный?
  2. Как я могу получить доступ ones снаружи этого класса? Через статическую переменную? Или я могу положить его в приложение контекст?

Edit:

Надеюсь, следующий псевдокод прояснит мои намерения.

OnesRun.ones = getCurrentValueOnes();

while ( (number = readNumbersFromFile) != null) {
   threadPool.execute(new OnesRun(number));
}

print("Overall values of ones " + OnesRun.ones);

Ответы [ 2 ]

7 голосов
/ 06 апреля 2011

Как увеличить потокобезопасность?

Вы можете использовать AtomicInteger.

Как я могу получить доступ к тем, кто находится за пределами этого класса? Через статическую переменную? Или я могу поместить это в контекст приложения?

Вы можете использовать простой метод получения. Или я что-то упустил?

Обновление

В зависимости от вашего обновления, вот как я могу изменить ваш пример кода:

public class OnesRun implements Runnable {

    private static final AtomicInteger ones = new AtomicInteger();

    private final int passendNumber;

    public OnesRun(int passendNumber) {
        this.passendNumber = passendNumber;
    }

    public void run() {
        if (passendNumber == 1)
            OnesRun.ones.incrementAndGet();
    }

    public static void setOnes(int newValue) {
        ones.set(newValue);
    }

    public static int getOnes() {
        return ones.get()
    }
}

...

OnesRun.setOnes(getCurrentValueOnes());

while ( (number = readNumbersFromFile) != null) {
   threadPool.execute(new OnesRun(number));
}

print("Overall values of ones " + OnesRun.getOnes());

Помимо того, что уже обсуждалось (создание ones a private static AtomicInteger и добавление пары геттер / установщик), я сделал оба члена final, что всегда желательно, если это возможно, особенно в параллельном коде.

Обратите также внимание, что AtomicInteger хранится как деталь реализации - он не предоставляется открытым интерфейсом класса.

0 голосов
/ 06 апреля 2011

Используйте AtomicInteger (потокобезопасный) и статическое свойство.

public class OnesRun implements Runnable {
    private static final AtomicInteger ones = new AtomicInteger();

    private int passendNumber;

    public OnesRun(int passendNumber) {
        this.passendNumber = passendNumber;
    }

    public void run() {
        if (passendNumber == 1) {
            ones.incrementAndGet();
        }
    }

    public static AtomicInteger getOnes() {
        return ones;
    }
}


OnesRun.getOnes().set(getCurrentValueOnes());

while ( (number = readNumbersFromFile) != null) {
    threadPool.execute(new OnesRun(number));
}

print("Overall values of ones " + OnesRun.getOnes().get());
...