synchronized同步方法(菜鳥玩執行緒)
阿新 • • 發佈:2018-12-19
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個鎖。