Почему объекты Java кэшируются? - PullRequest
1 голос
/ 14 сентября 2010

Зачем нам нужно кэширование объектов Java? Кто-нибудь может привести пример из реальной жизни, который требует кеширования объектов? Кроме того, расскажите о некоторых аспектах, связанных с дизайном и типами кэширования, а также о последствиях кэширования при многопоточном выполнении. Каковы все API, поддерживающие кэширование в Java?

Зачем мне нужен отдельный Caching API, поскольку в памяти могут быть простые объекты Java.

Ответы [ 2 ]

6 голосов
/ 14 сентября 2010

Вам не нужно для кэширования объектов, однако вы можете сделать это для экономии памяти, ресурсов ввода-вывода, ресурсов ЦП и т. Д.

Память

Например, JVM может кэшировать Integer объекты, всякий раз, когда вы просите создать новый объект, она может просто возвращать ссылку на уже существующий объект с тем же значением.Узнайте больше о шаблоне Flyweight .

CPU

Вы можете сэкономить ресурсы CPU, сохраняя результаты, для расчета которых требуется много CPU, в кэш-памяти.Связанная техника: Заметки .

Ввод / вывод

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

Запрошенный пример:

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

Кэширующее решение может заключаться в том, чтобы считывать цену акций раз в минуту, а затем хранить ее в поточно-ориентированном режиме.объект.Каждый поток (представляет запросы от ваших одновременных пользователей) будет читать из этого объекта вместо того, чтобы каждый раз обращаться к веб-API (экономия сетевого ввода / вывода) .

Объект является потокомбезопасно, поэтому потоки не будут читать это кэшированное значение в несогласованном состоянии, пока оно обновляется каждую минуту.

Таким образом, каждый из клиентов должен ждать, пока другой клиент завершит свою задачу?

Sidenote: это проблема параллелизма, а не проблема кеширования.

Нет, не обязательно, поскольку существуют поточно-ориентированныеструктуры, которые не будут блокироваться при чтении .Более того, в этом примере есть только один поток, который будет обновлять объект (периодическое обновление цены за одну минуту).

Чтобы уточнить, скажем, мы будем кэшировать эти цены акций в ConcurrentHashMap<String, BigDecimal> где строка представляет символ акции, "GOOG", "ORCL", "MSFT" и т. Д., А BigDecimal представляет цену / котировку акции.

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

price = quotesMap.get("GOOG"); // get Google stocks quote

Вызов ConcurrentHashMap.get () - это потокобезопасный неблокирующий (не влечущий за собой блокировку) вызов,и ваши несколько потоков могут одновременно выполнять поиск с карты.

Безопасность обеспечивается тем, что на все ваши вызовы get () будет поступать самое последнее завершенное обновление (выполненное по вашей цене).обновление потока при вызове ConcurrentHashMap.put() для обновления кэша цен.

4 голосов
/ 14 сентября 2010

Вы хотите кэшировать объекты, когда процесс их создания стоит очень дорого, это верно для чтения данных с диска по сравнению с RAM на аппаратном уровне вплоть до языка программирования высокого уровня, такого как Java.Если для создания объекта требуется 10 мс, а для извлечения этого объекта из кэша - 1 мс, при условии, что вы повторно используете объекты, у вас может быть 10 мс + 1 мс для создания объекта и его повторное использование, или 10 мс + 10 мс для создания объекта.объект дважды.Чем больше повторного использования, тем лучше выполняется кэширование.

Когда вы пишете многопоточную программу, вам нужно подумать о параллельном доступе к вашим объектам, если у вас есть объект банковского счета и два потокапрочитав баланс и обновив его, вы можете получить оба потока, читающие одно и то же значение и записывающие новое значение, основанное на этом, поэтому два вклада в 100 фунтов стерлингов могут привести к тому, что баланс вашего банка увеличится только на 100 фунтов стерлингов в качестве второго потокаОбновление имело устаревшее значение для текущего баланса.

В пакете java.util.concurrent имеется множество классов для работы с параллелизмом, а также ключевое слово synchronized.Здесь много ресурсов от Oracle здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...