Κοινή χρήση τεχνολογίας

Ασφάλεια νήματος (2) Η βασική αρχή υλοποίησης της δομής συγχρονισμένης, αναβάθμισης κλειδώματος και μνήμης αντικειμένων

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. Βασική χρήση

  • Ας υποθέσουμε ότι υπάρχει ένα τέτοιο σενάριο:20 χρήστες αρπάζουν 10 εισιτήρια μαζί

1.1 Εφαρμογή κώδικα χωρίς κλείδωμα

public class TicketDemo {
   

    // 票总数
    private int ticketNum = 10;

    /**
     * 抢票
     */
    public void getTicket() {
   
        if (ticketNum <= 0) {
   
            return;
        }
        System.out.println(Thread.currentThread().getName() + " 抢到一张票,剩余:" + ticketNum);
        // 非原子性操作
        ticketNum--;
    }

    /**
     * 测试:20个人抢一张票
     */
    public static void main(String[] args) {
   
        TicketDemo ticketDemo = new TicketDemo();
        for (int i = 0; i < 20; i++) {
   
            new Thread(ticketDemo::getTicket).start();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

Αποτελέσματα των:

Μπορείτε να δείτε ότι εμφανίζεται πρόβλημα υπερπώλησης , υπάρχουν 10 εισιτήρια συνολικά Όταν 20 νήματα αρπάζουν εισιτήρια μαζί, 11 άτομα φαίνεται να έχουν αρπάξει τα εισιτήρια. Αυτό συμβαίνει γιατί αν και τα δύο νήματα περάσουν τον έλεγχο if ταυτόχρονα.

Επομένως, πρέπει να κλειδώσουμε τη λειτουργία του εισιτηρίου για να διασφαλίσουμε ότι μόνο ένα νήμα μπορεί να ελέγξει και να λειτουργήσει την έκπτωση του εισιτηρίου ταυτόχρονα.

1.2 Εφαρμογή κώδικα κλειδώματος

public class TicketDemo {
   

    // 锁
    private static Object lock = new Object();

    // 票总数
    private int ticketNum = 10;

    /**
     * 抢票
     */
    public void getTicket() {
   
        synchronized (lock) {
   
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16