2015-08-05 2 views
2

Я переменная AtomicInteger объявлена ​​как переменная экземпляра, как это:AtomicInteger переменные в лямбда-выражения

public class Test_class { 
    AtomicInteger status_flag = new AtomicInteger(1); 
    public Test_class() { 
    } 
    ... 

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

public void some_class_func() { 
... 

for (int i=0; i< 10 && status_flag.get() == 1; i++) { 
    ... 
    dummy_func(x, test_lambda -> { 
     ... 
     if (some error occurs) { 
      status_flag.set(0); 
     } 
     ... 
    }); 
}//END for 
}//END func 

Является ли это правильный способ сделать это, чтобы быть уверенным, что не будет никаких проблем параллелизма? Если новый поток генерируется для каждого i в выражении лямбда, могу ли я быть уверенным, что использование AtomicInteger будет гарантировать, что цикл for будет читать правильное значение status_flag?

Благодарим за помощь.

EDIT: Я использую Vert.x Framework, который использует асинхронное программирование.

+1

Вам нужны какие-либо операции copmpareAndSet? если не достаточно летучего булева. или энергонезависимой, если только один поток обращается к ней. – the8472

+1

Почему не 'AtomicBoolean'? –

+1

@TagirValeev, если вам действительно не нужны операции, предоставляемые классами «Atomic *», поле volatile имеет меньшую площадь памяти и меньше ограничений. – the8472

ответ

2

Нет потоков не будет автоматически порождал, когда вы делаете одно из следующих действий:

  1. создать лямбда;
  2. передать его методу;
  3. вызов метода функционального интерфейса, реализуемого лямбдой.

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

+0

Hi Marko ..Я использую структуру Vert.x, которая использует асинхронное программирование. Таким образом, лямбда обрабатывается как отдельный поток. Если да, является ли этот код еще безопасным? –

+1

'AtomicInteger' является потокобезопасным. Однако, без подробностей, невозможно сказать, действительно ли это необходимо. «Быть ​​обработанным в другом потоке» недостаточно информации, чтобы быть убедительной. –

0

Если вы явно не создаете свои собственные потоки (которые вы не должны делать в Vertx), тогда у вас не будет проблем.

От Vertx docs

»... Это означает, что вы можете написать весь код в приложение в виде одного с резьбой и пусть Vert.x беспокоиться о многопоточности и масштабирования. Нет больше беспокоиться о синхронизирован и нестабильны, а вы также избегаете многих других случаев гоночных условий и тупиков, которые так превалируют при выполнении ручного «традиционного» многопоточного приложения развития ».

Единственным исключением является использование multi-threaded worker verticle, которого вы, скорее всего, не являетесь, и, скорее всего, этого не нужно.

Если вы создаете новую тему в своем методе, вам нужно спросить себя, почему? Это почти всегда нежелательно в Vert.x. Если вам нужна какая-то форма parallelism, подумайте о отправке своих «заданий» в EventBus и получите еще один Verticle процесс: настройка number of instances обработки задания verticles на количество параллельных процессов, которые вы хотите запустить.

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