Size: a a a

2020 November 15

S

Sergei in pro.jvm
UsernameAK
даже если не увидят, у меня все равно есть флаг который показывает что надо переобойти всё
"Переобойти" может никак не помочь. Один поток может писать данные в массив, второй будет "переобходить" - но записанных данных не увидит.
источник

U

UsernameAK in pro.jvm
Sergei
"Переобойти" может никак не помочь. Один поток может писать данные в массив, второй будет "переобходить" - но записанных данных не увидит.
почему?
источник

U

UsernameAK in pro.jvm
ведь переобход после сигнала из другого потока
источник

S

Sergei in pro.jvm
UsernameAK
почему?
"Java memory model"
источник

S

Sergei in pro.jvm
Потоки могут иметь свою локальную копию памяти, которая синхронизируется по определённым правилам (опять же, см. Java memory model).
источник

S

Sergei in pro.jvm
Из-за этого один поток может записывать данные, другой как будто читать ровно эти же данные - но "не видеть" изменений.
источник

S

Sergei in pro.jvm
У меня был пример про это.
источник

U

UsernameAK in pro.jvm
Sergei
Потоки могут иметь свою локальную копию памяти, которая синхронизируется по определённым правилам (опять же, см. Java memory model).
        if (this.isUpdateStarted && !this.updateInProgress.get()) {
           this.isUpdateStarted = false;
           
           // do things
       }

       if (this.isDirty) {
           this.isDirty = false;

           this.updateInProgress.set(true);
           this.isUpdateStarted = true;
           this.updateDiscardFlag.set(true);

           executor.execute(() -> {
               this.updateDiscardFlag.set(false);

               // do things

               if (this.updateDiscardFlag.get()) {
                   // discard everything
               } else {
                   this.updateInProgress.set(false);
               }
           });
       }
источник

U

UsernameAK in pro.jvm
если в общем, у меня так
источник

U

UsernameAK in pro.jvm
isDirty меняется откуда-то извне
источник

U

UsernameAK in pro.jvm
executor однопоточный
источник

S

Sergei in pro.jvm
Без внятной синхронизации данные изменённые в одном потоке могут в другой просто не приехать.
источник

S

Sergei in pro.jvm
Вот пример где два потока пишут в одну и ту же переменную (как будто), но изменения не доезжают.
https://github.com/sleepytomcat/java-exercises/blob/master/volatile/Volatile.java
источник

U

UsernameAK in pro.jvm
я не догоняю немного походу, но тут явно happens-before за счёт атомарных флагов, нет?
источник

S

Sergei in pro.jvm
UsernameAK
        if (this.isUpdateStarted && !this.updateInProgress.get()) {
           this.isUpdateStarted = false;
           
           // do things
       }

       if (this.isDirty) {
           this.isDirty = false;

           this.updateInProgress.set(true);
           this.isUpdateStarted = true;
           this.updateDiscardFlag.set(true);

           executor.execute(() -> {
               this.updateDiscardFlag.set(false);

               // do things

               if (this.updateDiscardFlag.get()) {
                   // discard everything
               } else {
                   this.updateInProgress.set(false);
               }
           });
       }
Из примера не особо понятно, какой поток что куда пишет, и как происходит синхронизация. Но какую-то синхронизацию иметь необходимо.
источник

S

Sergei in pro.jvm
UsernameAK
я не догоняю немного походу, но тут явно happens-before за счёт атомарных флагов, нет?
Да, это как раз оно.
источник

U

UsernameAK in pro.jvm
Sergei
Да, это как раз оно.
а, ну значит всё нормально)
источник

U

UsernameAK in pro.jvm
по крайней мере оно работает
источник

U

UsernameAK in pro.jvm
Sergei
Из примера не особо понятно, какой поток что куда пишет, и как происходит синхронизация. Но какую-то синхронизацию иметь необходимо.
запись происходит в другом месте вообще, в главном потоке
источник

U

UsernameAK in pro.jvm
массив я опустил для наглядности, оставив лишь синхронизацию
источник