„Здрасти, Амиго!“

„Здравей, Ели!“

„Искам да ви разкажа за летливия модификатор. Знаете ли Howво е това?“

— Нещо свързано с конци. Не помня точно.

„Тогава слушайте. Ето някои технически подробности за вас:“

„Един компютър има два вида памет: глобална (обикновена) памет и памет, вградена в процесора. Вградената памет на процесора е разделена на регистри, кеш от първо ниво (L1), кеш от второ ниво (L2) и трето ниво (L3)."

"Тези типове памет имат различни скорости. Най-бързата и най-малката памет са регистрите, след това кеша на процесора (L1, L2, L3) и накрая глобалната памет (най-бавната)."

„Глобалната памет и кешът на процесора работят с много различни скорости, така че Java машината позволява на всяка нишка да съхранява най-често използваните променливи в паметта на локалната нишка (в кеша на процесора).“

„Може ли този процес по няHowъв начин да бъде контролиран?“

„Не съвсем. Цялата работа се извършва от Java машината. Тя е много интелигентна, когато става въпрос за оптимизиране на производителността.“

„Но ето защо ви казвам това. Има един малък проблем. Когато две нишки работят с една и съща променлива, всяка може да съхранява копие в собствения си локален кеш. И тогава една нишка може да промени променливата, но втората може да не види промяната, защото все още работи със собствено копие на променливата."

— Е, Howво може да се направи тогава?

„Създателите на Java предоставиха специална ключова дума за тази ситуация: volatile. Ако дадена променлива е достъпна от различни нишки, трябва да я маркирате с модификатора volatile, така че Java машината да не я поставя в кеша. Ето How обикновено изглежда:"

public volatile int count = 0;

„О, спомням си. Вече споменахте това. Вече знам това.“

— Разбира се, че го правиш. Но си го спомни едва когато ти казах.

— Ъ-ъ, добре, малко съм позабравил.

"Повторението е майка на ученето!"

„Ето няколко нови факта за модификатора volatile. Модификаторът volatile гарантира само, че променливата ще бъде прочетена и записана безопасно. Не гарантира, че тя ще бъде променена безопасно.“

"Каква е разликата?"

„Вижте How се променя променливата:“

Код Какво наистина се случва: Описание
count++
register = count;

register = register+1;

count = register;
Стъпка 1.
Стойността на променливата count се копира от глобалната памет в регистър на процесора.

Стъпка 2.
Вътре в процесора регистрационната променлива се увеличава с 1.

Стъпка 3.
Стойността на променливата се копира от процесора в глобалната памет.

"Уау! Значи всички променливи се променят само в процесора?"

— Да.

"И стойностите се копират напред и назад: от паметта към процесора и обратно?"

— Да.

„Нестабилният модификатор гарантира, че когато се осъществи достъп до променливата count, тя ще бъде прочетена от паметта (стъпка 1). И ако дадена нишка иска да присвои нова стойност, тя определено ще бъде в глобалната памет (стъпка 3).“

„Но Java машината не гарантира, че няма да има превключване на нишки между стъпки 1 и 3.“

„Така че увеличаването на променливата с 1 всъщност е три операции?“

— Да.

"И ако две нишки едновременно искат да изпълнят count++, тогава те биха могли да си пречат?"

„Да, вижте го:“

Тема 1 Нишка 2 Резултат
register1 = count;
register1++;
count = register1;
register2 = count;
register2++;
count = register2;
register1 = count;
register2 = count;
register2++;
count = register2;
register1++;
count = register1;

„И така, можете да получите достъп до променливата, но промяната й все още е рисковано?“

„Е, можеш да го промениш, само внимавай ☺“

"Как?"

" Синхронизираният  е нашият най-добър приятел."

"Виждам."