Как не забыть порядок параметров

Обсуждаются как существующие проекты (перевод документации, информационная система и т.п.), так и создание новых.

Модератор: Модераторы

Re: Как не забыть порядок параметров

Сообщение Максим » 19.04.2014 00:22:40

скалогрыз писал(а):Итог: билдер патерн, нужен только в Яве, в паскале он не нужен! Ура! Ява программисты, пишите больше и толще! :mrgreen:

Гг. :mrgreen:
Аватара пользователя
Максим
энтузиаст
 
Сообщения: 598
Зарегистрирован: 27.07.2007 01:51:43
Откуда: Москва

Re: Как не забыть порядок параметров

Сообщение Mirage » 19.04.2014 11:06:37

скалогрыз писал(а):я не говорил про струтурное программирование, я говорил про "отсутствие подпрограмм" ;) специально-же цитату посдставляю!
...и выражаю своё сомнение в твоей уверенности, относительно того как и что оптимизирует процессов.


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

скалогрыз писал(а):Очереднёсть инструкций гарантируется в паскале для конкретного потока.
Это значит, что создав объект, я точно уверен, что все пременные в нём как надо, и я могу спокойно его раздавать в другие потоки


Ага, т.е. ты уверен, что если на момент получения ссылки на сконструированный объект, все команды по его инициализации находятся выше по тексту программы, то его можно передавать другим потокам?
И действительно, если в этом же потоке проверить все поля, то будут получены правильные значения!
Но, тем не менее, другой поток может увидеть не правильные.
Причем, что совсем не очевидно, даже если оставить проверки в первом потоке.

скалогрыз писал(а):По твоим утверждениями, такой гарантии (даже для одно потока) в Яве нет. ...но на самом деле есть, но это неважно.


Это вот по этому например?

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


Ну-ну.

скалогрыз писал(а):Тебе нужен явный контроль видимости данных. Я полагаю, сейчас в твоих проектах все данные доступны всем (потокам) всегда и контроль ведётся только за счёт иммутабельности.


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

скалогрыз писал(а):Радости мало, зато очень точно и эффективно можно контроллировать что, куда и когда попадёт.
Контроль = Надёжность.


Точнее всего контролировать позволит написание на ассемблере, т.к. примитивы синхронизации у каждого процессора свои.
Да и как ты без ассемблера или volatile проконтролируешь, что переменная пишется именно в память, а не, скажем, в регистр?
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Как не забыть порядок параметров

Сообщение скалогрыз » 20.04.2014 06:33:40

Mirage писал(а):А не надо мнений. Если полагаешь, что процессоры оптимизируют код, учитывая специальным образом команды call, ret и т.п., то покажи место в спецификации конкретного процессора, где такое написано.

Гугл в помощь! :mrgreen: никакого желания нет курить мануалы процессоров :mrgreen:

Mirage писал(а):Ага, т.е. ты уверен, что если на момент получения ссылки на сконструированный объект, все команды по его инициализации находятся выше по тексту программы, то его можно передавать другим потокам?

повторюсь - да.

Mirage писал(а):И действительно, если в этом же потоке проверить все поля, то будут получены правильные значения!
Но, тем не менее, другой поток может увидеть не правильные.
Причем, что совсем не очевидно, даже если оставить проверки в первом потоке.

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

Mirage писал(а):Иммутабельность очевидно не отменяет ни инкапсуляцию, ни другие принципы. Просто позволяет избежать необходимости синхронизации там, где она не нужна. Единственная проблема - неопределенность момента (с т.з. других потоков), когда все данные иммутабельного объекта инициализированы до своих значений. И эта проблема решается гарантиями конструктора таких объектов.
У тебя в примере эта проблема тоже решается (хотя ты тут её существование отрицаешь) явными и довольно тяжелыми синхронизациями.

И ты успешно ограничил использование своих объектов конструктором и чтение данных

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

Я же утверждаю, что другой поток, НЕ сможет получить доступ к объекту, пока я ему сам не передам этот объект.
А это значит, что я не ограничен в том, как я буду инициализировать объект.

Mirage писал(а):Точнее всего контролировать позволит написание на ассемблере, т.к. примитивы синхронизации у каждого процессора свои.
Да и как ты без ассемблера или volatile проконтролируешь, что переменная пишется именно в память, а не, скажем, в регистр?

Вопрос регистр, не регистр - остаётся компилятору, и рассматривается компилятором. А т.к. такого понятия как "volatile" в паскале нет, то и компилятору с этим вопросом проще.

"Тяжёлые" синхронизации гарантируются на уровне операционной системы-> заботится о конкретном процессоре не приходится -> в программе нет никаких ассемблерных вставок -> кроссплатформенный код.

Ну и общий стиль программы сохраняется:
* всё что может быть использовано разными потоками, должно позаботится о синхронизации, используя "тяжёлые" объекты синхронизации (а других-то средств синхронизации нет)
* всё что не может быть использовано разными потоками, должно быть использовано только одним потоком (например все GUI вызовы изначально предназначены для использования только из основного потока)
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Как не забыть порядок параметров

Сообщение Mirage » 20.04.2014 13:07:23

скалогрыз писал(а):Гугл в помощь! :mrgreen: никакого желания нет курить мануалы процессоров :mrgreen:


Зачем тогда пытаться использовать как аргумент то, о чем понятия не имеешь? :lol:

скалогрыз писал(а):повторюсь - да.


А другой поток его сам взять может?

скалогрыз писал(а):только если ты передал ссылку на объект второму потоку, до конца инициализации
(даже ява-устав тебе об этом говорит).


Ты, видать, подзабыл. Напомню:
Устав Java писал(а):The usage model for final fields is a simple one: Set the final fields for an object in that object's constructor; and do not write a reference to the object being constructed in a place where another thread can see it before the object's constructor is finished. If this is followed, then when the object is seen by another thread, that thread will always see the correctly constructed version of that object's final fields. It will also see versions of any object or array referenced by those final fields that are at least as up-to-date as the final fields are.


Т.е. это про только final-поля.
Обычные поля таким свойством не обладают и могут иметь дефолтные значения после конструктора, даже если они явным образом инициализировались в нем. Почему - из-за вышеобсужденных эффектов оптимизаций компилятора и процессора. Т.е. это отнюдь не магия явы. Чтобы этого не было, на современном железе нужно принимать специальные меры.

скалогрыз писал(а):я отрицаю "эту проблему" в твоей формулировке.
Потому что ты утверждаешь, что другой поток может получить доступ к не инициализированному объекту, без твоего ведома.
И потому, ты требуешь сделать инициализацию атомарной и втиснутой в единый конструктор.


Это фантазия очередная, я такого не утверждал. И уж совсем ничего не требовал.
За атомарность как раз ты утверждал, даже без конструктора. :wink:

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


Т.е. если ты передашь ссылку другому потоку "как положено", т.е. с синхронизацией, то наплевать на гарантии конструктора (а также функции-инициализатора вместе со структурным программированием тоже)?
Сразу бы так сказал, я бы сразу согласился. :lol:

скалогрыз писал(а):Вопрос регистр, не регистр - остаётся компилятору, и рассматривается компилятором. А т.к. такого понятия как "volatile" в паскале нет, то и компилятору с этим вопросом проще.


Компилятору-то проще "рассмотреть вопрос" о использовании регистра, а вот программисту, если ему надо на это повлиять, ох как не просто. :lol:

скалогрыз писал(а):"Тяжёлые" синхронизации гарантируются на уровне операционной системы-> заботится о конкретном процессоре не приходится -> в программе нет никаких ассемблерных вставок -> кроссплатформенный код.


Ну т.е. везде вставляем тяжелые синхронизации и радуемся жизни. И тормозам.
Я же за наличие возможностей легкой синхронизации - volatile, атомарные операции, CAS'ы и т.п.
Причем включенных в платформу (в случае FPC - в компилятор и RTL) так, чтобы все это было удобно в использовании и при этом предсказуемо работало.

скалогрыз писал(а):* всё что может быть использовано разными потоками, должно позаботится о синхронизации, используя "тяжёлые" объекты синхронизации (а других-то средств синхронизации нет)


Да ладно? А мужики-то не знают...
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Как не забыть порядок параметров

Сообщение hinst » 20.04.2014 17:25:16

Interlocked-функции в FPC доступны
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Как не забыть порядок параметров

Сообщение Mirage » 20.04.2014 19:58:11

Да, я в курсе. Даже барьеры, насколько я помню, есть.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Как не забыть порядок параметров

Сообщение скалогрыз » 21.04.2014 07:10:54

Mirage писал(а):Зачем тогда пытаться использовать как аргумент то, о чем понятия не имеешь? :lol:

точно знаю, что out-of-order execution на итоговый результат не влияют.
т.е. выражение ( 2 + 2 ) * 2 всегда будет давать результат 8, а не 6.
И не важно, что в процессоре закешировано (2+2) или ??? * 2
Соответственно с инструкциями "ret" тоже самое.

Mirage писал(а):А другой поток его сам взять может?

это как так "взять"?

Mirage писал(а):Ты, видать, подзабыл. Напомню:
Устав Java писал(а):The usage model for final fields is a simple one: Set the final fields for an object in that object's constructor; and do not write a reference to the object being constructed in a place where another thread can see it before the object's constructor is finished. If this is followed, then when the object is seen by another thread, that thread will always see the correctly constructed version of that object's final fields. It will also see versions of any object or array referenced by those final fields that are at least as up-to-date as the final fields are.


Т.е. это про только final-поля.
Обычные поля таким свойством не обладают и могут иметь дефолтные значения после конструктора, даже если они явным образом инициализировались в нем. Почему - из-за вышеобсужденных эффектов оптимизаций компилятора и процессора. Т.е. это отнюдь не магия явы. Чтобы этого не было, на современном железе нужно принимать специальные меры.


и снова возвращаемся к примеру из устава
Код: Выделить всё
class FinalFieldExample {
    final int x;
    int y;
    static FinalFieldExample f;

    public FinalFieldExample() {
        x = 3;
        y = 4;
    }

    static void writer() {
        f = new FinalFieldExample();
    }

    static void reader() {
        if (f != null) {
            int i = f.x;  // guaranteed to see 3 
            int j = f.y;  // could see 0
        }
    }
}

вот что я утверждаю (прошу согласится или нет с каждым утверждением)
1. public FinalFieldExample() - это конструктор
2. y = 4 присваивается в теле конструктора
3. int j = f.y; // could see 0 - ситуация "see 0" может возникнуть только в том, случае если конструктор не завершён.
4. f = new FinalFieldExample(); - вызов конструктора присваивает ссылку на объект раньше, чем конструктор завершён (иначе случая в пункте 3 не могло бы быть)
5. исходя из пункта 4, я могу судить, что данный код - это пример некорректного использования final полей, т.к. сказано: " do not write a reference to the object being constructed in a place where another thread can see it before the object's constructor is finished."

Mirage писал(а):
скалогрыз писал(а):я отрицаю "эту проблему" в твоей формулировке.
Потому что ты утверждаешь, что другой поток может получить доступ к не инициализированному объекту, без твоего ведома.
И потому, ты требуешь сделать инициализацию атомарной и втиснутой в единый конструктор.


Это фантазия очередная, я такого не утверждал. И уж совсем ничего не требовал.

хм... может быть я тебя на правильно понял:
1) требование внести инициализацию в конструктор, т.к. только он может что-либо гарантировать.
Mirage писал(а): Единственная проблема - неопределенность момента (с т.з. других потоков), когда все данные иммутабельного объекта инициализированы до своих значений. И эта проблема решается гарантиями конструктора таких объектов.

2) утверждение про потоки (состояние "гонок"):
Mirage писал(а):И действительно, если в этом же потоке проверить все поля, то будут получены правильные значения!
Но, тем не менее, другой поток может увидеть не правильные.



Mirage писал(а):За атомарность как раз ты утверждал, даже без конструктора. :wink:

Атомарность для одного потока. Требование на то, чтобы ссылка на объект передавалась другим потокам по завершению инизициализации (конструктора, функции, функций, методов... и какого угодно кода) остаётся.

Mirage писал(а):Т.е. если ты передашь ссылку другому потоку "как положено", т.е. с синхронизацией, то наплевать на гарантии конструктора (а также функции-инициализатора вместе со структурным программированием тоже)?

я не понимаю, что ты здесь пытаешься сказать.
Если ты указываешь на то, что я передаю указатель используя явные объекты синхронизации, то отвечу:
В принципе, я могу без проблем передать указатель на объект в поток. (естественно после инициализации объекта).
Это ничему не повредит, и работать приложение будет как ожидается.
-
Но в последствии я получу другую проблему - в какой момент времени можно объект освободить.
Это не проблема, если поток работающий с объектом один - он может и может освободить объект.
А вот если потоков несколько? или объект должен быть использован после того как поток проделал с ним работу. В итоге, я упираюсь в необходимость иметь явную синхронизацию.

Mirage писал(а):Компилятору-то проще "рассмотреть вопрос" о использовании регистра, а вот программисту, если ему надо на это повлиять, ох как не просто. :lol:

А тебе не надо на него влиять (...пока asm функции не начнёшь писать).
Больше того, тебе вредно на него влиять. Ещё хуже, ты НЕ можешь на него повлиять никак. Даже если опишешь все переменные как "register" или "volatile" или ещё как-нибудь.
Переменных много, а регистров набор строго ограничен (живописен и разнообразен на разных процессорах), все не поместятся, и что-то перейдёт в память.

Mirage писал(а):Ну т.е. везде вставляем тяжелые синхронизации и радуемся жизни. И тормозам.
Я же за наличие возможностей легкой синхронизации - volatile, атомарные операции, CAS'ы и т.п.
Причем включенных в платформу (в случае FPC - в компилятор и RTL) так, чтобы все это было удобно в использовании и при этом предсказуемо работало.

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

Mirage писал(а):Да ладно? А мужики-то не знают...

Могут и не знать, а если и знаю, быть может им религия запрещает?!
Мужики до сих пор проблемы и глюки с многопоточностью огребают.
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Как не забыть порядок параметров

Сообщение hinst » 21.04.2014 13:42:15

Я всё таки считаю, что моя первоначальная идея с заменой функций на небольшие объекты полезна.
У меня например есть своя функция, которая называется FormatFloat, и у неё два параметра: максимальная длина результирующей строки и значение типа Double
Код: Выделить всё
FormatFloat(MaxFloatLength, Max);
FormatFloat(Max, MaxFloatLength);
FormatFloat.MaxLength(MaxFloatLength).Value(Max).F

Я лично за то, чтобы было одной возможностью прострелить себе ногу меньше. Иначе я смотрю на эти вызовы и думаю, так что же там первым идёт, длина строки или само число? Вдруг перепутал?
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Как не забыть порядок параметров

Сообщение GrayEddy » 21.04.2014 14:44:27

Ага, атака клонов :)
GrayEddy
постоялец
 
Сообщения: 375
Зарегистрирован: 06.05.2005 09:37:56

Re: Как не забыть порядок параметров

Сообщение stanilar » 21.04.2014 15:28:36

hinst писал(а):так что же там первым идёт, длина строки или само число

Поставим вопрос шире: какая из переменных "Max" и "MaxFloatLength" является длиной строки, а что самим числом?
stanilar
постоялец
 
Сообщения: 289
Зарегистрирован: 09.03.2010 19:09:02

Re: Как не забыть порядок параметров

Сообщение hinst » 21.04.2014 16:10:37

MaxFloatLength у меня длина строки, а Max это само число
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Как не забыть порядок параметров

Сообщение stanilar » 22.04.2014 18:11:23

hinst писал(а):MaxFloatLength у меня длина строки, а Max это само число

А как не перепутать их при подстановке в "билдер"?
stanilar
постоялец
 
Сообщения: 289
Зарегистрирован: 09.03.2010 19:09:02

Re: Как не забыть порядок параметров

Сообщение Mirage » 22.04.2014 21:02:21

скалогрыз писал(а):точно знаю, что out-of-order execution на итоговый результат не влияют.
т.е. выражение ( 2 + 2 ) * 2 всегда будет давать результат 8, а не 6.
И не важно, что в процессоре закешировано (2+2) или ??? * 2
Соответственно с инструкциями "ret" тоже самое.


Ничего не понял, что к чему...

скалогрыз писал(а):это как так "взять"?


Модель памяти она о чем вообще? Она о том, что увидит один поток в памяти, в результате действий другого, параллельного.

скалогрыз писал(а):и снова возвращаемся к примеру из устава
...
вот что я утверждаю (прошу согласится или нет с каждым утверждением)
1. public FinalFieldExample() - это конструктор
2. y = 4 присваивается в теле конструктора
3. int j = f.y; // could see 0 - ситуация "see 0" может возникнуть только в том, случае если конструктор не завершён.
4. f = new FinalFieldExample(); - вызов конструктора присваивает ссылку на объект раньше, чем конструктор завершён (иначе случая в пункте 3 не могло бы быть)
5. исходя из пункта 4, я могу судить, что данный код - это пример некорректного использования final полей, т.к. сказано: " do not write a reference to the object being constructed in a place where another thread can see it before the object's constructor is finished."


1. Ага.
2. Ага.
3. Смотря как определить с т.з. другого потока понятие "конструктор завершен".
С одной стороны, f.y еще не присвоен. Значит, конструктор не завершен.
С другой, переменной f уже даже присвоена ссылка на объект, что даже видно из другого потока, откуда и вызывается reader(). Значит, конструктор завершен. :lol:
4. Не, не раньше. Из того же потока как не смотри, не раньше. Если передать раньше, то с final полями тоже беда будет.
5. Не, с final полями-то все как раз хорошо. Та часть конструктора, что инициализирует final поля, гарантированно отработала, в полном соответствии с заявленной моделью памяти.

скалогрыз писал(а):хм... может быть я тебя на правильно понял:
1) требование внести инициализацию в конструктор, т.к. только он может что-либо гарантировать.
Mirage писал(а): Единственная проблема - неопределенность момента (с т.з. других потоков), когда все данные иммутабельного объекта инициализированы до своих значений. И эта проблема решается гарантиями конструктора таких объектов.


Я ничего не требовал, а описывал одно из возможных решений проблемы. И конструктор тут не атомарен сам по себе. Просто если правильно все сделать, то об объекте ничего не узнают, пока не станет можно.

скалогрыз писал(а):2) утверждение про потоки (состояние "гонок"):
Mirage писал(а):И действительно, если в этом же потоке проверить все поля, то будут получены правильные значения!
Но, тем не менее, другой поток может увидеть не правильные.


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

скалогрыз писал(а):Атомарность для одного потока. Требование на то, чтобы ссылка на объект передавалась другим потокам по завершению инизициализации (конструктора, функции, функций, методов... и какого угодно кода) остаётся.


Атомарность с т.з. одного потока тут не поможет. Там и так все атомарно, если исключения не вылезет. :lol:
Объект ты можешь публиковать по завершении чего угодно, но если нет механизма, который бы гарантировал, что все эти завершения будут видны другому потоку, то тебе придется использовать явные синхронизации, казалось бы, на ровном месте. Что ты и делаешь. :lol:

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


Как именно ты обеспечишь, что для другого потока это будет тоже "после инициализации объекта"?

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


Это уже другая проблема, причем изолированная. Её в любом случае придется как-то решать, независимо от того, синхронизировался ты при передаче объектов, или нет. Хотя в последнем случае до этой проблемы программа может и не дожить. :lol:

скалогрыз писал(а):А тебе не надо на него влиять (...пока asm функции не начнёшь писать).
Больше того, тебе вредно на него влиять. Ещё хуже, ты НЕ можешь на него повлиять никак. Даже если опишешь все переменные как "register" или "volatile" или ещё как-нибудь.
Переменных много, а регистров набор строго ограничен (живописен и разнообразен на разных процессорах), все не поместятся, и что-то перейдёт в память.


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

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


скалогрыз писал(а):Кстати - про тормоза - пожалуйста с тестами и сравнением производительности.


Какими тестами? Сравнение критических секций (synchronized) и волатильных переменных можно нагуглить при желании.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Как не забыть порядок параметров

Сообщение скалогрыз » 22.04.2014 22:18:48

Mirage писал(а):
скалогрыз писал(а):...
вот что я утверждаю (прошу согласится или нет с каждым утверждением)
3. int j = f.y; // could see 0 - ситуация "see 0" может возникнуть только в том, случае если конструктор не завершён.
4. f = new FinalFieldExample(); - вызов конструктора присваивает ссылку на объект раньше, чем конструктор завершён (иначе случая в пункте 3 не могло бы быть)
5. исходя из пункта 4, я могу судить, что данный код - это пример некорректного использования final полей, т.к. сказано: " do not write a reference to the object being constructed in a place where another thread can see it before the object's constructor is finished."


3. Смотря как определить с т.з. другого потока понятие "конструктор завершен".
С одной стороны, f.y еще не присвоен. Значит, конструктор не завершен.
С другой, переменной f уже даже присвоена ссылка на объект, что даже видно из другого потока, откуда и вызывается reader(). Значит, конструктор завершен. :lol:
4. Не, не раньше. Из того же потока как не смотри, не раньше. Если передать раньше, то с final полями тоже беда будет.
5. Не, с final полями-то все как раз хорошо. Та часть конструктора, что инициализирует final поля, гарантированно отработала, в полном соответствии с заявленной моделью памяти.

Я не понял насчёт коментариев №3 и №4
А почему в твоём комментарии 3 ты пишешь "переменной f уже даже присвоена ссылка на объект" и сразу в 4 "Не, не раньше (чем конструктор завершён ). Из того же потока как не смотри, не раньше".

:? :? :?

Надо думать, что понятие "конструтор завершён" и "Та часть конструктора гарантированно отработала" не относится к понятию "код был выполнен".
Код был выполнен, то что ты говоришь, на самом деле (перевод с миражского на скалогрызский):
"не факт что, те значения которые были записаны в потоке 1, доступны потоку 2, т.к. у потока 1 свой кеш и очень может быть, что поток 1 писал в кеш".

Все "финальные" поля, находтся за барьером памяти (и ты это уже писал). А значит, как только происходит присвоение последнему final полю, поток №1 вызвовет барьерную инструкцию, и все значения финальных полей окажутся в общей памяти (что обеспечит видимость их актуальных значений потоку 2).

при этом поток №1 продожин выполнять конструтор, заполнив все не финальные поля (которые окажутся в кеше потока 1).
после этого поток №1 присвоит значение "f" (которое тоже заполнится в его кеш).

в какой конкретный момент времени значение f и f.y перейдут из кеша потока в общую память - неизвестно (дано на откуп процессору/операционке?).
в каком порядке они перейдут в общую память, тоже не известно. Потенциально может оказаться, что f окажется в общей памяти раньше, чем f.y.
Что и вызовет проблему, обозначенную в уставе (где f уже есть, а f.y ещё нет, хотя если следить по коду такое невозможно).

т.к. переход Final полей в общую гарантирован - ты ратуешь за их использование в ущерб их изменяемости значений (что накладывает ряд ограничений!).
либо вожделеешь volatile, что при присвоении значений тоже будет принудительно сливать кеш потока в память (и обеспечивать "видимость изменений")

при моём подходе, ни то не другое не нужно (да и не доступно), а объекты синхронизации сами вызвают барьер памяти. Который казалось бы излишен, но в итоге всё-равно не обходим, т.к. память всегда нужна в актуальном состоянии.
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Как не забыть порядок параметров

Сообщение hinst » 23.04.2014 14:36:19

что-то вы удалились от первоначального вопроса

Добавлено спустя 7 минут 20 секунд:
который насчёт порядка параметров
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Пред.След.

Вернуться в Разное

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 29

Рейтинг@Mail.ru