Jawa / Говнокод #22606 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
private Map<String, PreparedStatement> statements = new ConcurrentHashMap<>();

public PreparedStatement prepare(String cql) {

    cql = cql.toLowerCase();

    synchronized (cql.intern()) {
        if (!statements.containsKey(cql)) {
            PreparedStatement statement = session.prepare(cql);
            statements.put(cql, statement);
        }
    }

    return statements.get(cql);
}

Ручное кеширование com.datastax.driver.core.PreparedStateme nt с синхронизацией на String.intern(). Кажется, годно для публикации!

Запостил: jericho jericho, (Updated )

Комментарии (19) RSS

  • это просто современный модный способ написания "Sleep(Random() % 10)"
    Ответить
    • а разве есть какойто смысл использовать ConcurrentHashMap в синхронизированном контексте или другими словами ConcurrentHashMap уже thread safe и нет смысла его синкать еще раз 🙂
      Ответить
      • от рэйс кондишнов "thread safe" структуры не спасают - у тебя ведь здесь два доступа. хотя в данном контексте максимум что произойдет, это два одинаковых стейтмента будут prepare'd ренундантно - но в мапе в конце все равно будет только один элемент.
        Ответить
          • и да, и нет. да - потому что желаемый эффект. нет - потому что залочит мап пока prepare будет исполнятся. в коде сверху, мап незалочен пока prepare исполняется. если препаре тормозной (как он типично в базах) то это очень сильно нежелаемый эффект.

            PS
            https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html#computeIfAbsent-K-java.util.function.Function-

            но как здесь описывается, то вроде бы чтение из мапа не будет заблокировано - только запись в мап. не совсем желательно - но часто это достаточно.
            Ответить
            • Переделать на computeIfAbsent() здесь ок.

              Исходники у этого метода, канеш, вырви глаз, но мапа полностью не лочится. Здесь как и везде в конкаррент мапе есть а ля бакеты, которые вычисляются для каждой строки cql. То есть в случае коллизий будет лочиться только один бакет.
              Ответить
      • > нет смысла его синкать еще раз

        А кто сказал, что session.prepare(cql); потокобезопасен?

        Тут смех скорее не в блокировках, а в том, как происходит инвалидация кэша.

        Что происходит с PreparedStatement, когда сессия закрывается?
        Кто удаляет старые записи из кэша?
        Ответить
        • > Кто удаляет старые записи из кэша?

          "Java uses garbage collection, thus there are no memory leak by design. You simply need to install more RAM on your servers."
          Ответить
        • Если ещё подумать, то это должна быть обёртка над session, и кэш должен удаляться при закрытии сессии.
          Ответить
        • > А кто сказал, что session.prepare(cql); потокобезопасен?

          Что-то я и сам затупил. Лок тут используется не для того, чтобы защитить session, и не для того, чтобы защитить мапу.

          Он тут используется для того, чтобы не подготавливать один и тот же запрос дважды.

          Осталось проверить, является ли session потокобезопасным.
          Ответить
          • Session - это из cassandra driver. В доках по кассандре как раз рекомендуется использовать один объект сессии на все приложение. Так что он потокобезопасен.
            Ответить
        • Конкретно здесь никто не удаляет. Уникальных кверей не много. Заботится об инвалидации смысла нет. К тому же приложение регулярно рестартуется.
          Ответить
        • Что происходит с PreparedStatement, когда сессия закрывается?

          Сессия закрывается при остановке приложения. То есть все время жизни приложения PreparedStatement абсолютно валиден.
          Ответить
  • В рот мне ноги. Увидел капчу с буквами - охерел.
    Наконец-то за сайт взялись
    а меня пронесло?
    Ответить

Добавить комментарий

Я, guest, находясь в здравом уме и твердой памяти, торжественно заявляю:

    А не использовать ли нам bbcode?


    8