Как получить экземпляр класса make-потока, если он кешируется в следующий раз - PullRequest
0 голосов
/ 16 декабря 2011

У меня есть класс контекста. Итак, я создаю экземпляр класса. Поскольку этот класс выполняет сложные и дорогостоящие математические операции, я не хочу делать это каждый раз. Так что я кеширую класс.

Что если я создаю новый экземпляр, что если другой поток приходит и получает тот же экземпляр из кэша?

Есть ли решение этой проблемы ...?

Ответы [ 4 ]

0 голосов
/ 16 декабря 2011

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

class CostyThingCache { 

    static ThreadLocal<CostyClass> cache = new ThreadLocal<CostyClass>() {

        // This gets called once ever per thread:
        @Override
        protected CostyClass initialValue() {
            return new CostyClass();
        }

    };

    static CostyClass getCostyThing() {
        return cache.get();
    }

}

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

0 голосов
/ 16 декабря 2011

Зависит от реализации кеша.Сильно зависит от того, какими частями вы можете управлять.

0 голосов
/ 16 декабря 2011

Я полагаю, вы говорите о защите своего кэша от условий гонки .Состояние гонки возникает, когда два или более потоков обращаются к общему ресурсу (в данном случае к вашему кешу) одновременно без надлежащей защиты.

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

  1. Использование ключевого слова synchronized, конечно, может помочь защитить кэш отусловия гонки.Поток, добавляющий экземпляр вашего класса в кеш, будет синхронизироваться в кеше при его вставке.Потоки, получающие экземпляр из кэша, также будут синхронизироваться.

  2. Если экземпляр вашего класса должен использоваться только одним потоком за раз, тогда вы можете использовать BlockingQueue размером один.Экземпляр вашего класса может быть добавлен в очередь, и потоки будут ждать, пока один не получит экземпляр.Когда это будет сделано, он поместит его обратно в BlockingQueue, позволяя следующему потоку получить класс.

  3. Убедитесь, что экземпляр вашего класса полностью инициализирован, когда он помещается в кеш.

Если вы отредактируете свой вопрос и предоставите образец кода или более подробную информацию, мы поможем вам лучше.

0 голосов
/ 16 декабря 2011

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

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