потокобезопасность массива Java

Здесь есть две вещи:

  • re.findall возвращает захваченные тексты, если шаблон регулярного выражения содержит в нем группы захвата
  • часть r'\\.' в вашем шаблон соответствует двум последовательным символам, \ и любому символу, отличному от новой строки.

См. ссылку findall :

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

blockquote>

Обратите внимание, что чтобы re.findall возвращали только совпадающие значения, вы обычно можете

  • удаляет избыточные группы захвата (например, (a(b)c) -> abc)
  • преобразует все группы захвата в , не захватывая (то есть замените ( на (?:) , если отсутствуют обратные ссылки, которые относятся к значениям группы в шаблоне (см. ниже)
  • вместо re.finditer использовать [x.group() for x in re.finditer(pattern, s)])

В вашем случае findall вернул все захваченные тексты, которые были пустыми, потому что вы \\ в [литерале] строки r'', которые пытались сопоставить литерал \.

Чтобы соответствовать номерам, вам нужно использовать

-?\d*\.?\d+

Регулярное выражение соответствует:

  • -? - Дополнительный знак минус
  • \d* - Необязательные цифры
  • \.? - Дополнительный десятичный разделитель
  • \d+ - 1 или более цифр.

См. demo

Вот демон IDEONE :

import re
s = r'abc123d, hello 3.1415926, this is my book'
pattern = r'-?\d*\.?\d+'
L = re.findall(pattern, s)
print(L)

24
задан Jason S 15 July 2009 в 17:17
поделиться

5 ответов

Хотя вы не получите недопустимое состояние путем изменения массивов, как вы упомянули, у вас будет та же проблема, которая возникает, когда два потока просматривают энергонезависимое целое число без синхронизации (см. Раздел Обучающее руководство по Java на Память Ошибки согласованности ). По сути, проблема в том, что Поток 1 может записать значение в пространство i, но нет гарантии, когда (или если) Поток 2 увидит изменение.

Класс java.util.concurrent.atomic.AtomicIntegerArray делает то, что вы хотите сделать.

15
ответ дан Sean Bright 29 November 2019 в 00:16
поделиться

Поскольку read () не синхронизирован, у вас может быть следующий сценарий:

Thread A enters write() method
Thread A writes to nwriting = 0;
Thread B reads from nwriting =0;
Thread A increments nwriting. nwriting=1
Thread A exits write();

Так как вы хотите гарантировать, что ваши переменные адреса никогда не конфликтуют, как насчет чего-либо подобного (исключая проблемы с индексами массива):

int i;
synchronized int curr(){ return i; }
synchronized int next(){ return ++i;}

int read( ) {
         return values[curr()];
     }

void write(int x){
   values[next()]=x;
}
0
ответ дан Steve B. 29 November 2019 в 00:16
поделиться

В этом примере много вещей, которые отличаются от вопроса в прозе.

Ответ на этот вопрос состоит в том, что отдельные элементы доступа к массиву осуществляются независимо, поэтому вам не нужна синхронизация, если два потока изменяют разные элементы.

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

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

4
ответ дан 29 November 2019 в 00:16
поделиться

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

2
ответ дан 29 November 2019 в 00:16
поделиться

Да, поскольку неправильное чередование кэша все еще может происходить в среде с несколькими процессорами / ядрами. Есть несколько способов избежать этого:

  • Использовать небезопасную частную библиотеку Sun для атомарной установки элемента в массиве (или добавленную функцию jsr166y в Java7
  • Использовать AtomicXYZ [] array
  • Использовать настраиваемый объект с одним volatile и иметь массив этого объекта.
  • Используйте ParallelArray из добавления jsr166y вместо этого в своем алгоритме
2
ответ дан 29 November 2019 в 00:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: