java中synchronized的關鍵字

java中每一個對象都會有一個對象鎖,而synchronized就是獲得這個鎖,看下面這個例子java

import java.util.Random;
public class MyData{
    
    public synchronized void increment() {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(new Random().nextInt(200));
            } catch (Exception e) {
                e.printStackTrace();
            }
           System.out.println(Thread.currentThread().getName() + ":" +i);
        }
    }
    
    public synchronized void decrement() {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(new Random().nextInt(200));
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ":" +i);
        }
    }
    
    public static void main(String[] args) {
        final MyData myData1 = new MyData();
       // final MyData myData2 = new MyData();
       new Thread(new Runnable() {
            @Override
            public void run() {
                myData1.increment();
            }
        }).start();
        
        new Thread(new Runnable() {
            @Override
            public void run() {
                myData1.decrement();
            }
        }).start();
    }
}

 

不管執行多少次都是有序的,兩個線程操做的是同一個對象,第一個執行的線程獲得了鎖,第二個線程只能等第一個線程執行完了才能拿到鎖,進入方法。dom

再看下面這個例子ide

import java.util.Random;
public class MyData{
    
    public synchronized void increment() {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(new Random().nextInt(200));
            } catch (Exception e) {
                e.printStackTrace();
            }
           System.out.println(Thread.currentThread().getName() + ":" +i);
        }
    }
    
    public synchronized void decrement() {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(new Random().nextInt(200));
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ":" +i);
        }
    }
    
    public static void main(String[] args) {
        final MyData myData1 = new MyData();
        final MyData myData2 = new MyData();
       new Thread(new Runnable() {
            @Override
            public void run() {
                myData1.increment();
            }
        }).start();
        
        new Thread(new Runnable() {
            @Override
            public void run() {
                myData2.decrement();
            }
        }).start();
    }
}

執行的結果是無序的,兩個對象,兩把鎖,故互不影響,各自執行各自的。spa

再來看看下面這個例子線程

import java.util.Random;
public class MyData{
    
    public synchronized void increment() {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(new Random().nextInt(200));
            } catch (Exception e) {
                e.printStackTrace();
            }
           System.out.println(Thread.currentThread().getName() + ":" +i);
        }
    }
    
    public static synchronized void decrement() {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(new Random().nextInt(200));
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ":" +i);
        }
    }
    
    public static void main(String[] args) {
        final MyData myData1 = new MyData();
      //  final MyData myData2 = new MyData();
       new Thread(new Runnable() {
            @Override
            public void run() {
                myData1.increment();
            }
        }).start();
        
        new Thread(new Runnable() {
            @Override
            public void run() {
                MyData.decrement();
            }
        }).start();
    }
}

結果也是無序的,緣由和上面同樣,static方法是屬於Class對象的,故decrement方法鎖的MyData.Class對象,而myData1.increment();鎖的是myData1對象,互不干擾。code

只需記住synchronized鎖的是對象,每一個對象有一把對象鎖,拿到鎖以後才能執行synchronized的方法對象

相關文章
相關標籤/搜索