Разделяет ли Runnable структуру данных, если они меняются? - PullRequest
0 голосов
/ 04 мая 2019

Я создаю Runnable следующим образом:

public class AbcRunnable implements Runnable
{
     Qwe qwe;

     Rst rst;

     public void run() {

        // some operations on qwe and rst which are changing their value
     }
}

public class AbcThreadPool {

    private final AbcThreadPoolExecutor executor;

    public InventoryAvailabilityThreadPool(final AbcRunnableFactory factory,
                                           final Integer poolSize) {
        executor = new AbcThreadPoolExecutor(factory, poolSize);

        for (int i = 0; i < poolSize; ++i) {
            executor.execute(factory.get());
        }
    }

    private static class AbcThreadPoolExecutor extends ThreadPoolExecutor {

        private final AbcRunnableFactory factory;

        public AbcThreadPoolExecutor(final AbcRunnableFactory factory,
                                                       final int poolSize) {
            super(poolSize, poolSize, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
            this.factory = factory;
            allowCoreThreadTimeOut(false);
        }
    }
}

public class AbcRunnableFactory {

    @Override
    public AbcRunnable get() {
        return new AbcRunnable();
    }
}

Инициализация Qwe и Rst выполняется модулем guice, скажем, следующим образом:

@Provides
@Singleton
private AbcRunnableFactory provideAbcRunnableFactory() {
    return new AbcRunnableFactory(
        new Qwe(), new Rst());
}

ИтакЗдесь AbcRunnable имеет 2 переменные: qwe и rst.Мой вопрос здесь: есть ли у разных Runnable свои переменные или они становятся общими?Пожалуйста, помогите объяснить это.

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

Ответы [ 2 ]

2 голосов
/ 04 мая 2019

Каждый новый экземпляр AbcRunnable будет иметь свой собственный набор полей (list1 и map1). Так как ваш цикл вызывает factory.get() в каждой итерации, и это создает новый AbcRunnable, каждая задача пула потоков будет иметь уникальный экземпляр runnable и содержащихся в нем полей.

Теперь вы не показали, как инициализировать поля внутри AbcRunnable:

  • Если вы создаете новые экземпляры List и Map в конструкторе, то между потоками ничего не распределяется, и ваш код является поточно-ориентированным.
  • Если вы передаете какое-либо из этих значений извне, ваши различные экземпляры AbcRunnable могут потенциально делиться ссылками на один и тот же список / карту, и вам необходимо будет обеспечить синхронизированный доступ к данным (или использовать одновременный сборник). реализация, которая уже поточнобезопасна).
0 голосов
/ 04 мая 2019

Ответ зависит от того, как вы создаете свои исполняемые файлы. Здесь много чего происходит, поэтому давайте упростим. Скажем, у нас есть очень большой набор из n чисел, которые мы хотим сложить. Мы можем разделить набор на два и создать 2 потока, когда они возвращаются, мы просто суммируем два результата. Поскольку мы могли бы разделить набор на две части и суммировать в конце, нет ничего общего, все безопасно для потоков.

Теперь предположим, что мы хотим знать, сколько из наших n чисел было суммировано, когда они работают. Нам нужен общий счетчик, который каждый поток может увеличивать как сумму двух потоков. Таким образом, если счетчик равен 100 и оба потока пытаются увеличить его в одно и то же время, оба потока будут читать 100, добавить 1 и вернуть 101 в память, новый счет будет равен 101, но на самом деле 102 числа были суммированы. Для общих переменных, таких как наш счетчик, нам нужно убедиться, что только один поток одновременно имеет доступ, если они записывают в него.

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

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