4 thoughts on “(ქართული) მაღლიველი სტუდენტი და NASA-ს ჯავას სტანდარტი

  • Tuesday March 13th, 2018 at 04:28 AM
    Permalink

    ყველა ენას აქვს ასეთი “gotcha” მომენტები. ჯავაში ის მიყვარს, რომ თუ დაფიქრდები რატომ ხდება ასე, მიხვდები ადვილად, იმიტომ რომ გააზრებული და კარგად დამუშავებული ენაა. შეადარე ჯავასკრიპტს ან პერლს. მთელი აიტი სფეროს ხუმრობების მიზანია, ისეთი აუხსნელი რამეები ხდება.

    > ეს იმიტომ რომ int დაყავს char-ზე
    პირიქით იგულისხმე მგონი.

    volatile-ს რაც შეეხება, ძალიან სუსტი დაცვაა და უმეტეს შემთხვევაში არ აკეთებს იმას, რაც სინამდვილეში გინდა. მაგისთვის შექმნეს atomic კლასები (AtomicInt, AtomicLong, etc) და ჯობია ყოველთვის ისინი გამოიყენო volatile-ის ნაცვლად.

    Reply
    • Tuesday March 13th, 2018 at 08:27 AM
      Permalink

      დიდი მადლობა 🙂 სწორი შენიშვნაა, პირიქით უნდა დამეწერა char-ზე და ჩავასწორე.
      მეც იგივე აზრზე ვარ, რომ მშვენივრად დალაგებულია ენა და ფაქტიურად ყველაფერი ლოგიკურად აიხსნება.

      volatile-ს რაც შეეხება, როგორც მესმის იგივეს არ აკეთებს რასაც atomic კლასები. უბრალოდ უზრუნველყოფს რომ არ დაკეშირდეს ცვლადი და ნაკადები ახალ მნიშვნელობას ხედავდნენ. მარტო წაკითხვა არის ატომური, სხვა არაფერი და ატომური ოპერაციებისთვის არ გამოდგება. საერთოდ flag ტიპის ცვლადების გარდა ამის გამოყენება არ შემხვედრია.

      Reply
      • Tuesday July 17th, 2018 at 03:28 PM
        Permalink

        იდეაში, წაკითხვაც და ჩაწერაც, ცალცალკე, ატომური ოპერაციებია, volatile-ის შემთხვევაში პრობლემა სხვა რაღაცაშია. მაგალითად ინკრიმენტი არის ორი ოპერაცია: ძველი მნიშვნელობის წაკითხვა და ახალი მნიშვნელობის ჩაწერა. ამ ორ ოპერაციას შორის, volatile-ის შემთხვევაში, შეიძლება ცვლადის მნიშვნელობა უკვე სხვა ნაკადს ჰქონდეს შეცვლილი და საბოლოოდ არასწორი შედეგი მივიღოთ. მაგალითად ორ ნაკადში ვაინკრემენტებთ x ცვლადს, x++ საშუალებით, თეორიულად შესაძლებელია მოხდეს შემდეგი რამ:

        > volatile int x = 0
        > ნაკადი 1: წაიკითხა x = 0
        > სანამ პირველმა ნაკადმა ჩაწერა გაზრდილი მნიშვნელობა, მეორე ნაკადმაც წაიკითხა, რომ x = 0
        > ორივე ნაკადი ინკრემენტს უკეთებს 0-ს და x-ს ანიჭებს მნიშვნელობას 1, ჩვენი მოლოდინით კი x უნდა ყოფილიყო 2.

        ამის თავიდან ასაცილებლად საჭირო იქნებოდა synchronized ბლოკის გამოყენება. Atomic ცვლადები კი შეიძლება ითქვას, რომ volatile-იც არის და synchronized-იც. მაგალითად AtomicInteger-ს თუ ვეტყვით incrementAndGet() ინკრემენტაცია ერთ ოპერაციაში მოხდება და დარწმუნებული ვიქნებით, რომ ოპერაციის შესრულებამდე სხვა ნაკადი ცვლადის მნიშვნელობას ვერ შეცვლის. პროცესორებს აქვთ ატომური ოპერაციების მხარდაჭერა, რომლებსაც არ აქვთ, იმათთვის JVM თავისით აგვარებს, რომ სინქრონიზებული იყოს Atomic ცვლადებზე ოპერაციები.

        Reply
        • Sunday July 29th, 2018 at 11:19 PM
          Permalink

          მადლობა კომენტარისთვის.

          მესმის კი 🙂 ზუსტად მაგას ვგულისხმობ მეც, რომ Atomic და volatile სულ სხვადასხვა დანიშნულებით გამოიყენება. volatile ორ-ნაბიჯიან ოპერაციას არ იცავს. ერთადერთი რისი გაკეთებაც შეუძლია, არის რომ არ დაკეშირდეს ცვლადის მნიშვნელობა და ყველა ნაკადი მის ახალ ვერსიას ხედავდეს (იმიტომ რომ ისე კეშირება ხდება ცვლადების).

          ‘მხოლოდ წაკითხვა არის ატომური’ ამაში ვგულისხმობ, რომ 32 ბიტზე დიდი ტიპები რაც არის, მაგალითად long და double, ერთიანად არ იკითხება. შეიძლება პირველი 32 ბიტი წაიკითხოს, მერე რამე ნაკადმა შეცვალოს მნიშვნელობა და ამან მეორე 32 ბიტი უკვე სხვა რაღაცისა აიღოს. volatile-ის დროს ამის დაზღვევა ხდება, რომ ატომურად მოხდეს მნიშვნელობის წაკითხვა.

          ინკრემენტს და სხვა მსგავს ოპერაციებს ვერ გასწვდება და სინქრონიზაცია ან Atomic იქნება ნამდვილად საჭირო. volatile მე მხოლოდ flag ტიპის ცვლადებზე შემხვედრია, სხვაგან არ ვიცი სად იყენებენ.

          Reply

Leave a Reply to admin Cancel reply

Your email address will not be published. Required fields are marked *