— გამარჯობა, Amigo!
არსებობს ასეთი დიდი თემა, ეწოდება Java Memory Model. პრინციპში ჯერ არ არის აუცილებელი რომ ეს იცოდე, მაგრამ იმის მოსმენა სასარგებლოა.
ყველა შესაძლო პრობლემის გაუმჯობესების მიზნით, Java-ში მეხსიერების მექანიზმი შეცვალეს. ახლა მეხსიერება არა მხოლოდ ადგილობრივ კეშზე და გლობალურ, არამედ მექანიზმი კიდევ უფრო უკეთესი გახდა.
— და უფრო რთული!
— დიახ, უკეთესი და რთული. ეს როგორც თვითმფრინავია. თვითმფრინავით ფრენა უკეთესია, ვიდრე ფეხით სიარული, მაგრამ უფრო რთულია. ვეცდები, გაგაგებინო ახალი სიტუაცია ძალიან გამარტივებულად.
აი, რა მოიფიქრეს. კოდში დამატებულია სინქრონიზაციის მექანიზმი ადგილობრივი მეხსიერების ნიტებისათვის, რომელსაც ეწოდება «happens before» (ნორმალურად „ხდება ადრე“). იყო მოფიქრებული რიგი წესების/პირობების, რომელთა დროს მეხსიერება სინქრონიზდება – განახლდება მიმდინარე მდგომარეობამდე.
მაგალითი:
თხრობის | ნიტი 1 | ნიტი 2 |
---|---|---|
1 2 … 101 102 103 104 105 … 201 202 203 204 205 |
|
ნიტი ელის mutex-ის განთავისუფლებას |
ერთ-ერთი ასეთი პირობა არის განთავისუფლებული mutex-ის დაჭერა. თუ mutex განთავისუფლდა და მეორად დაჭერილი იყო, მაშინ დაჭერის წინ აუცილებლად შესრულდება მეხსიერების სინქრონიზაცია. ნიტი 2 დაინახავს „ყველაზე ახალ“ მნიშვნელობებს ცვლადების x და y, თუნდაც ისინი არ იყოს გამოცხადებული, როგორც volatile.
— როგორი საინტერესო. და ბევრია ასეთი პირობები?
— საკმარისია, აი ზოგიერთი პირობა მეხსიერების სინქრონიზაციისთვის:
- ერთ ნიტში ნებისმიერი ბრძანება happens-before (შედის „ხდება ადრე“) ნებისმიერი ოპერაციის შემდეგ, რომელიც მის შემდეგაა საწყის კოდში.
- ლოკის განთავისუფლება (unlock) happens-before იგივე ლოკის დაჭერა (lock).
- გამოსვლა synchronized ბლოკიდან/მეთოდიდან happens-before შესვლა synchronized ბლოკში/მეთოდზე იმავე მონიტორზე.
- volatile ველის ჩანაწერი happens-before იმავე volatile ველის წაკითხვა.
- მეთოდის run დასრულება კლასის Thread-ის ეგზემპლარში happens-before მეთოდის join()-ის გამოსვლა ან ცრუ დაბრუნება isAlive() მეთოდის იმავე ნიტის ეგზემპლარით.
- მეთოდის start() გამოძახება კლასის Thread-ის ეგზემპლარზე happens-before იმავე ნიტის ეგზემპლარის run() მეთოდის დაწყება.
- კონსტრუქტორის დასრულება happens-before იმავე კლასის finalize() მეთოდის დაწყება.
- მეთოდის interrupt() გამოძახება ნიტზე happens-before, როდესაც ნიტმა აღმოაჩინა, რომ ეს მეთოდი გამოძახებული იყო, ან გამონაკლის InterruptException-ის მეშვეობით, ან მეთოდების isInterrupted() ან interrupted()-ის მეშვეობით.
— ანუ ყველაფერი ცოტათი რთულია, ვიდრე ვფიქრობდი?
— დიახ, ცოტათი რთულია…
— მადლობა, რიშა, ვიფიქრებ ამისთვის.
— ძალიან ნუ გაწუხდება ამ თემასთან დაკავშირებით. მოვა დრო, თავად გაიგებ ყველაფერს. ჯერ უკეთესია, რომ ძირეულები გაიგო, ვიდრე Java-მშენის შიგნით ზედმეტობაში ჩასვლა.
— ო_ო. მ-და. ზოგი რამ უკეთესი არ იცოდეს.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ