Java модел памет за кратко, Java специалист
Java Memory Model накратко
Двете основни неща, които въвеждат ентропия в многонишков код - това пренареждане и видимостта.
Видимостта (видимост)
Една нишка може в някакъв момент временно съхраняване на стойността на някои полета не са в основната памет и регистрите или локалния кеш на процесора, така че втората нишка се изпълнява на друг процесор, четене от основната памет, не могат да видят най-новите промени в областта. И обратно, ако за известно време потокът на работата с местни регистри и кеш, четене на данните от там, той не може веднага да видите промените, извършени от друга нишка в основната памет.
Пренареждането
За да се увеличи производителността на процесора / компилатор може да се пренареди някои инструкции / операции. По-скоро от гледна точка на потока, следи за изпълнението на операциите в различен поток, операции могат да бъдат извършвани не в реда, в който те са в изходния код.
Така reorderinga същия ефект може да се наблюдава, когато един поток поставя първите резултати работа в регистър или локален кеш, а резултатът от втората операция поставя директно в основната памет. След втората нишка, позовавайки се на основната памет може да види най-напред в резултат на втората операция, първият и само тогава, когато всички регистри или кеш, са синхронизирани с основната памет.
Друга причина за преподреждане, може да се крие във факта, че процесорът може да вземе решение за промяна на реда на операциите, например, ако счита, че такава последователност се извършва по-бързо.
На практика това може да има много лоши последствия. Всичко, което каза, мисля, че проблемът в кода по-долу е от само себе си:
Все още е важно да се отбележи, че за операции в рамките на една нишка, спецификацията на JVM позволява да направи само такова пренареждане, което води до абсолютно същите резултати, както ако всички операции се извършват по начин, определен в изходния код от гледна точка на потока, в който се намира кода извършва. Т.е. в едно преподреждане поток никога не е виждал.
Станало преди-
В Java памет модел въведена такава абстракция като се случва-преди. Това означава, че съотношението, ако операцията е свързана с Х-случва преди операция с Y, а след това цялата операция код, последван от състоянието на Y, изпълнен в един конец вижда всички промени, направени от друг конец преди операцията X.
Списък на проекти, свързани нагласа се случва-преди:
Много важен момент: като освобождаване / улавяне монитора и запис / пишете на летливи променлива свързана нагласа се случва-преди, само ако операциите се извършват в един и същи обект инстанция.
Също така е важно да се разбере, че във връзка случва-преди участието на само две струи видимост и преподреждане на останалите потоци не мога да кажа нищо, докато всеки един от тях няма да дойде случва-преди отношения с другия поток.
Дори по отношение на се случва, преди да има много голям допълнителен бонус: това съотношение не само придава вид на летливи полета или резултатите от дейността, осигуряване на монитора или Лок, но също така и на външния вид на всички за всичко, което се прави, за да hapens-преди събитието.
Така че на горната фигура ThreadB гарантирана, за да видите промяна в ш. направен ThreadA, въпреки че не е летлив и писане, за да го гледа извън синхронизирани блока.
Описаните по-горе свойства могат да бъдат постигнати JVM, както следва: при отпускане на монитора (запис на летливи променлива, и още по-надолу в списъка) всички регистри и местните кешовете на процесора се синхронизират с основната памет, както и по време на последващото улавяне Лока (летливи променлива четене и т.н.) Процесор , на която вторият поток обезсилва кеша си и да прочетете всички най-нови данни от основната памет. Защо, тогава, е необходимо да се синхронизира на същия монитор, ще попитате вие? Да, защото само в този случай ще бъде гарантирана чрез строг ред, т.е. втора нишка е гарантирано да се отърват кеша, точно след първата синхрон с основната си памет.
Съотношението случва-преди налага сериозни ограничения на преподреждането. От гледна точка на Y поток са настъпили всички операции до точката случва-преди това в X на потока може да се счита за завършена операция в своя резба. Т.е. не логично преподреждане в сравнение с директното реда на източника по отношение на потока Y не може да бъде.
Ако се вгледаме внимателно на границата се случва, преди по отношение на промяна на поредността поток Y, тогава никаква операция е над случва-преди граници в поток X, не може да бъде изпълнена под границата случва-преди, в резултат на промяна на поредността обаче операции са под границите, разрешени изпълнение към нея. По-ясно е показано на фигурата.
публикуване на обекти
Този забележителен имот прави antipattern двойна проверка заключване работеща ако Сингълтън конструктор инициализира само крайният терена.
Точно този имот решава проблема с предишния модел на паметта, където използването повсеместно всичко на неизменни линия строго погледнато не винаги работи.
Как стана това имущество може да се реализира от JVM? Мисля, че JVM ще гарантира, че към момента на записването на референтен обект с главната памет, всички стойности постижими от крайните области, изложени по време на строителството, вече синхронизирани с основната памет. По този начин, всеки поток на четене позоваване на обект и е необходимо да се чете всички стойности показват начина, описан по време на строителството.
размисъл
Доколкото чух от един от служителите на Oracle в JavaSE щанд в последния JavaOne в Москва, се променят крайните области чрез размисъл и след последващото му четене случва през бариерата на паметта, така че в този случай е възможно да не се тревожи за достъп до крайните области от други източници , Всъщност, за мен това звучи малко странно и непонятно. Руслан, който чух за тази цел заедно с мен, изглежда твърде дълго при тази мисъл, и роди следващия пост като резултат.
статично инициализация
Атомност полета за четене и запис
JMM гарантира атомност на четене и запис не дълги / двойни области. Променлив - абсолютно всички области. Невярно представляваща референции на обекти, също винаги са написани четене атомично. Разбираемо е, че с тази спецификация не забранява да имат валентност рекорд четене дълго \ двойно поле за 64-битови виртуални машини. Това атомност гаранции, че всяка нишка по всяко време да четат от полето или стойността по подразбиране, или общата стойност записано там в някакъв момент от време, и никога няма да откриете, че има някои отломки.