идеи синхронизации для метода - PullRequest
2 голосов
/ 10 июля 2011

У меня есть многопоточный класс A, который обращается к следующему insert() методу другого класса B (A имеет только один экземпляр B).

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

private void insert(byte[] shardKey, byte[] queueKey, 
            byte[] value, PipelineMessageType msgType) {
        PipelineMessage pipelineMessage = new PipelineMessage(queueKey, 
                value, msgType);
        LinkedBlockingQueue<PipelineMessage> queue;
        JedisShardInfo shardInfo = shardedJedis.getShardInfo(shardKey);     // shardedJedis is an instance variable of this class
        String mapKey = shardInfo.getHost() + shardInfo.getPort();          
        queue = shardQueue.get(mapKey);         // shardQueue is an instance variable of this class                         
        boolean insertSuccessful = queue.offer(pipelineMessage);
        if(!insertSuccessful) {
            // perform the pipeline sync - flush the queue
            // use another thread for this

            // (processing of queue entries is given to another thread here)

            // queue would be empty now. Insert (k,v)
            queue.offer(pipelineMessage);
        }
    }

Я пытался синхронизировать только фрагмент, который обращается к переменным экземпляра, но может быть сценарий, когда 2 потока пытаются вставить в полную очередь и войти в блок if. Тогда 2 потока могут обработать записи в очереди, чего я не хочу.

Любые предложения приветствуются. Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 10 июля 2011

Ключ к правильной синхронизации заключается в следующем:

synchronize(lockObjectForState) { // All code that alters state must also synchronise on the same lock

    while(!stateOkToProceed()) {
        try {
            lockForState.wait();   
        } catch (InterruptedException e) {
            // handle if your thread was interrupted deliberately as a single to exit, or spuriously (in which case do nothing)
        }
    }

    updateState();

    lockForState.notifyAll();
}
Пакет

java.util.concurrent предлагает множество поточно-ориентированных реализаций классов, необходимых для решения общих проблем с многопоточностью. Попробуйте использовать BlockingQueue .

1 голос
/ 10 июля 2011

Мне кажется, что если JedisShardInfo будет элементом только для чтения, то вам необходимо его защитить / синхронизировать.Таким образом, вы можете синхронизировать только со строки

queue= ...

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

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

 Object lockerA = new Object() {};

 synchronized( lockerA )
 {}//sync

Ну, не так много, чтобы сказать.:)

С уважением, Стефан

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