Что Java эквивалентен из Взаимно блокируемого класса .NET?

Адаптированный от Не Так Часто Задаваемые Вопросы :

#include 
#include 
#include 

std::string data = "Abc";
std::transform(data.begin(), data.end(), data.begin(),
    [](unsigned char c){ return std::tolower(c); });

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

, Если Вы действительно ненавидите tolower() , вот специализированная альтернатива только для ASCII, что я не рекомендую использовать:

char asciitolower(char in) {
    if (in <= 'Z' && in >= 'A')
        return in - ('Z' - 'z');
    return in;
}

std::transform(data.begin(), data.end(), data.begin(), asciitolower);

знать, что tolower() может только сделать per-single-byte-character замену, которая является неподходящей для многих сценариев, особенно при использовании multi-byte-encoding как UTF-8.

15
задан ripper234 20 July 2009 в 08:25
поделиться

2 ответа

Используйте AtomicInteger .

29
ответ дан 1 December 2019 в 02:10
поделиться

Безопасность потока может быть достигнута с помощью синхронизированных функций. Оберните свой int (или такие данные) в класс, который предоставляет необходимые функции с помощью синхронизированных методов, например

public class X
{
  protected int x;
  public synchronized void set( int value )
  {
    x = value;
  }
}

. Вы также можете использовать классы из пакета java.util.concurrent.atomic , например, AtomicInteger или AtomicIntegerArray

Почему этот ответ не сработает

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

| Thread A      | Thread B         | 
|---------------|------------------|
| read x (x=4)  |                  |
|               | read x (x=4)     |
| Calculate 4+1 |                  |
| EAX ← 5       |                  |
|               | Calculate 4+1    |
|               | EAX ← 5          |
| Start sync    |                  |
| {             | Start sync       |
| { x ← 5       |    wait          |
| {             |    wait          |
| End sync      |    wait          |
|               | {                | 
|               | { x ← 5          |
|               | {                | 
|               | End sync         |

Конечный результат операций:

x = 4;
x += 1;
x += 1;

состоит в том, что x = 5 , а не 6.

Та же проблема существует с ключевым словом volatile . Ключевое слово volatile не спасает вас от эффектов потоков. Ключевое слово volatile только гарантирует, что

  • кеши очищаются до чтения переменной
  • кеши очищаются после записи значения

Строго говоря, volatile гарантирует, что операции с памятью не будут переупорядочены вокруг летучая переменная. Это означает, что вы все еще страдаете от проблемы:

  • чтение из x
  • запись в x

.

1
ответ дан 1 December 2019 в 02:10
поделиться