Как сделать так, чтобы два потока обращались к одному ресурсу и делали их потокобезопасными? - PullRequest
0 голосов
/ 02 июня 2019

Я новичок в многопоточности, и у меня есть несколько основных вопросов, на которые я не смог получить ответы.Допустим, у меня есть класс с именем BankTransaction, и я хочу обработать случай многопоточности.

CASE 1 (основанный на приложениях синглтон)

@Singleton (Application based singleton)
class BankTransaction {
    synchronized void doSomeTransaction() {
        // write operation
    }
}

Случай 2 (основанный на запросах синглтон)

@Singleton (Request based singleton)
class BankTransaction{
    synchronized void doSomeTransaction() {
        // write operation
    }
}

Вопросы

Пожалуйста, потерпите меня и объясните мне непрофессионала, как мне нужно прояснить ситуацию.

  1. В случае 1, если 1000 пользователейИспользуете один и тот же экземпляр (так как он основан на приложениях) класса BankTransaction и используете метод doSomeTransaction (), запросы для каждого из 1000 пользователей будут медленными?потому что он синхронизирован и будет работать потокобезопасно.Так что, это плохой подход.Правильно ли мое понимание?

  2. В случае 2, если те же 1000 пользователей используют метод doSomeTransaction () класса BankTransaction, каждый получит свои собственные экземпляры класса BankTransaction, и он получитникогда не будь медленным ни для одного из них.Но как мне справиться с состоянием гонки, когда, например, из этих 1000 пользователей 2 из них тесно связаны (муж и жена) и имеют доступ к одному и тому же банковскому счету и одновременно выполняют метод doSomeOperation ().Как мне справиться с этим?потому что оба они снова имеют 2 разных экземпляра класса BankTransaction, и может возникнуть несогласованность данных.

Ответы [ 2 ]

1 голос
/ 02 июня 2019
  1. Да. Ваше понимание верно. Вы должны синхронизировать метод, если вы не хотите, чтобы несколько пользователей могли изменять состояние объекта. Примером может служить объект конфигурации уровня приложения.

  2. Теперь есть много решений для этого. Проще всего было бы отложить эту проблему до некоторого решения ORM, которое может далее использовать технику блокировки на уровне записи или что-то еще. Однако, если вы хотите обработать это вручную, самый простой способ сделать это - поддерживать столбец в БД. Теперь, каждый раз, когда вы изменяете запись, вы должны увеличивать это значение. И перед фиксацией вашей записи вы должны проверить, совпадает ли значение со значением записи, которую вы извлекли из db. Если он такой же, то вы можете быть уверены, что никто не изменил его с момента запуска транзакции. Однако, если значение не совпадает, вы можете выдать ошибку пользователю, сообщив, что запись была изменена другим пользователем.

1 голос
/ 02 июня 2019
  1. В первом случае 1000 пользователей (или их потоки) будут ждать долго, потому что только один может получить доступ к методу за раз. Всем остальным придется ждать блокировки, чтобы получить доступ к этому методу. Так что да, это будет медленно.

  2. Если у каждого пользователя есть свой собственный экземпляр класса BankTransaction, он НЕ будет медленным, потому что блокировка метода относится к объекту (в этой реализации объектом блокировки будет «this»). Таким образом, пользователи (или их потоки) ждут только, если есть другой пользователь, который хочет использовать тот же метод точно такого же объекта (что не должно быть в случае, если у каждого пользователя есть свой собственный экземпляр).

...