Как синхронизировать геттер и сеттер в потоке

public class IntermediateMessage {

    private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private final Lock read = readWriteLock.readLock();
    private final Lock write = readWriteLock.writeLock();

    private volatile double ratio;

    public IntermediateMessage(){
        this.ratio=1.0d;
    }

    public IntermediateMessage(double ratio){
        this.ratio = ratio;
    }

    public double getRatio(){
        read.lock();
        try{
            return this.ratio;
        }
        finally{
            read.unlock();
        }
    }

    public void setRatio(double ratio){ 
        write.lock();
        try{
            this.ratio = ratio;
        }
        finally{
            write.unlock();
        }
    }
}

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

5 ответов

Решение

Вам нужна блокировка вообще? Скорее всего нет, согласно ограниченным требованиям, которые вы описали. Но прочитайте это, чтобы быть уверенным...

  • У вас есть только одна тема.
    • Это означает, что значение переменной никогда не может быть "устаревшим" из-за того, что конкурирующие авторы "забивают" друг друга (нет возможных условий гонки). Таким образом, не требуется блокировка для обеспечения целостности при рассмотрении отдельной переменной в отдельности.
  • Вы не упомянули, требуется ли некоторая атомарная согласованная модификация нескольких переменных. Я предполагаю, что это не так.
    • ЕСЛИ ratio всегда должен быть согласован с другими переменными (например, в других объектах) - т. е. если набор переменных должен изменяться синхронно как группа, в которой никто не читает только часть изменений, - тогда требуется блокировка, чтобы обеспечить атомарную согласованность для набора переменных, Затем непротиворечивые переменные должны быть изменены вместе в пределах одной заблокированной области, и читатели должны получить такую ​​же блокировку перед чтением любого из этих наборов переменных (ожидание в заблокированном состоянии, если необходимо).
    • Коэффициент IF может быть изменен в любое время как одиночная переменная, и его не нужно поддерживать согласованным с другими переменными, тогда не требуется блокировка, чтобы обеспечить атомарную согласованность для набора переменных.

Вам нужен модификатор volatile? Ну да!

  • У вас есть несколько тем для чтения.
  • Переменная может измениться в любой момент, включая мгновение, прежде чем она будет прочитана.
  • volatile Модификатор используется в многопоточных приложениях, чтобы гарантировать, что значение, читаемое "читателями", всегда совпадает со значением, записанным "писателями".

Для чтения / записи примитивного значения, volatile одного достаточно.

Вы делаете некоторое перерасход на синхронизацию, которая может вызвать некоторую неэффективность.

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

Таким образом, вы блокируете переменную, которая по умолчанию уже синхронизирована.

Поэтому вам следует либо удалить ключевое слово volatile, либо удалить повторяющиеся блокировки. Вероятно, энергозависимый, поскольку вы будете более эффективны при многократном чтении, как вы сейчас синхронизируете.

При условии, что два потока пытаются читать и писать на одном и том же объекте, и вы хотите, чтобы сохранялась целостность данных. Просто синхронизируйте ваш геттер и сеттер. Когда метод синхронизирован, только один поток сможет вызвать метод синхронизации. Пока один поток выполняет один из синхронизированных методов, ни один другой поток не сможет вызвать любой из синхронизированных методов. Так что в вашем случае, если у вас есть метод get & set, синхронизированный, вы можете быть уверены, что поток читает / пишет, никакой другой поток не может читать / писать.

Надеюсь, поможет!

Делать ratio окончательный и это будет потокобезопасным.

Другие вопросы по тегам