synchronized關鍵字淺談

我的總結:
java

synchronized 不能夠被繼承。
synchronized 修飾this,則表明鎖住對象,同一個對象互斥。
synchronized 修飾XXX.class,則表明鎖住字節碼,跟鎖住同一個類的class的邏輯和static function互斥。
synchronized 修飾靜態變量,則對於全部具備相同屬性值的對象互斥。
synchronized 修飾普通變量,則對於同一個對象,在該屬性值未變更以前互斥。
synchronized 修飾靜態方法,則對於全部對象訪問該方法互斥。
synchronized 修飾普通方法,則對同一個對象訪問該方法互斥。

一、非static方法
synchronized void method1()與void method1(){synchronized(this){}}是等價,都是對象鎖,鎖定固然對象實例。 
二、static方法
static 
synchronized void method1()與static void method1(){ synchronized (Foo.class){}}是等價,是等價的,鎖定Class的字節碼。

sleep和wait的區別有:
  1,這兩個方法來自不一樣的類分別是Thread和Object
  2,最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其餘線程可使用同步控制塊或者方法。
  3,wait,notify和notifyAll只能在同步控制方法或者同步控制塊裏面使用,而sleep能夠在
    任何地方使用
   synchronized(x){
      x.notify()
     //或者wait()
   }
  4,sleep必須捕獲異常,而wait,notify和notifyAll不須要捕獲異常
  5,調用sleep()和yield()的時候鎖並無被釋放,而調用wait()將釋放鎖。這樣另外一個任務(線程)能夠得到當前對象的鎖,
    從而進入它的synchronized方法中。能夠經過notify()/notifyAll(),或者時間到期,從wait()中恢復執行。
    只能在同步控制方法或同步塊中調用wait()、notify()和notifyAll()。
    若是在非同步的方法裏調用這些方法,在運行時會拋出IllegalMonitorStateException異常。

(若是有錯誤的地方或者沒有說明白的地方,請你們指出來,謝謝。)
ide

Foo 類

class Foo {
    private String name;
    private static String desc;
    private byte[] b = new byte[10];
    private static Foo foo;
    
    private Foo() {
        // TODO Auto-generated constructor stub
    }
    
    public static Foo getInstance(){
        if(null == foo ){
            foo = new Foo();
        }
        return foo;
    }
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public static String getDesc() {
        return desc;
    }

    public static void setDesc(String desc) {
        Foo.desc = desc;
    }

    public byte[] getB() {
        return b;
    }

    public void setB(byte[] b) {
        this.b = b;
    }

    public synchronized static void methodOne(String flag) {
        System.out.println("methodOne"+flag);
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void methodTwo(String flag) {
        System.out.println("**methodTwo**"+flag);
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    public void methodThrid(String flag){
        synchronized (this) {
            System.out.println("**methodThrid**"+flag);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public void methodFour(String flag){
        //synchronized鎖住屬性值,若是對於同一個對象,若是該屬性值同樣,則會互斥,若是不同的話,則不會互斥。
        synchronized (name) {
            System.out.println("**name**"+flag+name);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public void methodFive(String flag){
        //synchronized鎖住靜態屬性值,若是這個屬性值相同,則互斥,不然不互斥。
        synchronized (desc) {
            System.out.println("**desc**"+flag);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public void methodSix(String flag){
        
        synchronized (b) {
            System.out.println("**b**"+flag+b);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public void methodSeven(String flag){
        //synchronized鎖住class的時候,會跟class裏面的static function 互斥,不會跟普通function互斥。
        synchronized (Foo.class) {
            System.out.println("**Foo.class**"+flag);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
}



main 方法測試程序

for (int i = 0; i < 5; i++) {
            
            // start two thread
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Foo  f = Foo.getInstance();
                    f.setName("tttt");
                    //Foo.setDesc("ooo");
                    //f.methodTwo(Thread.currentThread().getName());
                    //Foo.methodOne(Thread.currentThread().getName());
                    //f.methodFour(Thread.currentThread().getName());
                    //f.methodFive(Thread.currentThread().getName());
                    //f.methodSeven(Thread.currentThread().getName());
                    f.methodSix(Thread.currentThread().getName());
                }
            }).start();
            
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    Foo  f = Foo.getInstance();
                    f.setName("pppp");
                    //Foo.setDesc("zzz");
                    //f.methodTwo(Thread.currentThread().getName());
                    //f.methodThrid(Thread.currentThread().getName());
                    //f.methodFour(Thread.currentThread().getName());
                    //Foo.methodOne(Thread.currentThread().getName());
                    //f.methodFive(Thread.currentThread().getName());
                    //f.methodSeven(Thread.currentThread().getName());
                    //f.methodSix(Thread.currentThread().getName());
                    
                }
            }).start();
        }
相關文章
相關標籤/搜索