1. 程式人生 > >synchronized同步方法(菜鳥玩執行緒)

synchronized同步方法(菜鳥玩執行緒)

synchronized同步方法

方法內的變數是執行緒安全的

實驗1:

共享變數類

package com.chapter02.thread1;

public class HasSelfPrivateNum {
    public void addI(String username) {
        int num = 0;
        try {
            if (username.equals("a")) {
                num = 100;
                System.out.println("a set over!");
                Thread.
sleep(2000); } else { num = 200; System.out.println("b set over!"); } System.out.println(username + " num = " + num); } catch (InterruptedException e) { e.printStackTrace(); } } }

自定義執行緒A

package com.chapter02.
thread1; public class ThreadA extends Thread { private HasSelfPrivateNum hasSelfPrivateNum; public ThreadA(HasSelfPrivateNum hasSelfPrivateNum) { super(); this.hasSelfPrivateNum = hasSelfPrivateNum; } @Override public void run() { super.run(); hasSelfPrivateNum.
addI("a"); } }

自定義執行緒B

package com.chapter02.thread1;
public class ThreadB extends Thread {
    private HasSelfPrivateNum hasSelfPrivateNum;
    public ThreadB(HasSelfPrivateNum hasSelfPrivateNum) {
        super();
        this.hasSelfPrivateNum = hasSelfPrivateNum;
    }
    @Override
    public void run() {
        super.run();
        hasSelfPrivateNum.addI("b");
    }
}

啟動類

package com.chapter02.thread1;
public class Run {
    public static void main(String[] args) {
        HasSelfPrivateNum hasSelfPrivateNum = new HasSelfPrivateNum();
        ThreadA threadA = new ThreadA(hasSelfPrivateNum);
        threadA.start();
        ThreadB threadB = new ThreadB(hasSelfPrivateNum);
        threadB.start();
    }
}

執行結果

a set over!
b set over!
b num = 200
a num = 100

結論

方法中的變數不存在非執行緒安全問題,永遠都是執行緒安全的。

例項變數是非執行緒安全的

實驗2:

共享變數類

package com.chapter02.thread1;

public class HasSelfPrivateNum {
    //todo 注意此處 synchronized 和 變數
    private int num = 0;
    synchronized public void addI(String username) {
        try {
            if (username.equals("a")) {
                num = 100;
                System.out.println("a set over!");
                Thread.sleep(2000);
            } else {
                num = 200;
                System.out.println("b set over!");
            }
            System.out.println(username + " num = " + num);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

自定義執行緒A

package com.chapter02.thread1;
public class ThreadA extends Thread {
    private HasSelfPrivateNum hasSelfPrivateNum;

    public ThreadA(HasSelfPrivateNum hasSelfPrivateNum) {
        super();
        this.hasSelfPrivateNum = hasSelfPrivateNum;
    }

    @Override
    public void run() {
        super.run();
        hasSelfPrivateNum.addI("a");
    }
}

自定義執行緒B

package com.chapter02.thread1;
public class ThreadB extends Thread {
    private HasSelfPrivateNum hasSelfPrivateNum;

    public ThreadB(HasSelfPrivateNum hasSelfPrivateNum) {
        super();
        this.hasSelfPrivateNum = hasSelfPrivateNum;
    }

    @Override
    public void run() {
        super.run();
        hasSelfPrivateNum.addI("b");
    }
}

啟動類

package com.chapter02.thread1;

public class Run {
    public static void main(String[] args) {

        HasSelfPrivateNum hasSelfPrivateNum = new HasSelfPrivateNum();
        ThreadA threadA = new ThreadA(hasSelfPrivateNum);
        threadA.start();

        ThreadB threadB = new ThreadB(hasSelfPrivateNum);
        threadB.start();

    }
}

執行結果

//如果不新增synchronized
a set over!
b set over!
b num = 200
a num = 200

//如果新增synchronized
a set over!
a num = 100
b set over!
b num = 200

結論

在兩個執行緒訪問同一個物件中的同步方法時一定是執行緒安全的。

多個物件對個鎖

修改實驗2程式碼,修改啟動類

package com.chapter02.thread1;

public class Run {
    public static void main(String[] args) {

        HasSelfPrivateNum hasSelfPrivateNumA = new HasSelfPrivateNum();
        ThreadA threadA = new ThreadA(hasSelfPrivateNumA);
        threadA.start();
	    
        HasSelfPrivateNum hasSelfPrivateNumB = new HasSelfPrivateNum();
        ThreadB threadB = new ThreadB(hasSelfPrivateNumB);
        threadB.start();

    }
}

輸出結果

a set over!
b set over!
b num = 200
a num = 100

結論

上面的示例 建立了2個HasSelfPrivateNum類的物件,所以產生了2個鎖。