多個物件多個鎖——T2104
阿新 • • 發佈:2021-01-13
package 物件及變數的併發訪問2;
/**
* 多個物件多個鎖
*
* 如果先輸出 a set over! a=100 然後輸出 b set over b=1200 就是同步,而如果輸出 a set over 後 輸出 b set over 就是非同步
*
* 本示例中,建立了兩個業務(A+B),在系統中產生兩個鎖,執行緒和業務物件屬於一對一的關係,每個執行緒執行自己所屬的業務物件中的同步方法,
*不存在爭搶關係,所以執行結果是非同步的,另外,在這種情況下,synchronized可以不需要,執行緒和業務物件屬於多對一的關係,為了避免出現
* 非執行緒安全問題,所以使用synchronized。
* 從程式結果看,雖然HasSelfPrivateNumT214使用了synchronized關鍵字,但輸出順序不是同步的,而是交叉的,關鍵字synchronized取得
*的鎖都是物件鎖,而不是把一段程式碼或方法當作鎖,所以在程式碼中,那個執行緒先執行synchronized關鍵字的方法,那個執行緒就持有該方法所屬物件的
* 鎖Lock,那麼其他執行緒只能處於等待狀態,前提是多個執行緒訪問的是同一個物件。但如果多個執行緒訪問多個物件,也就是每個執行緒訪問自己所屬的業務
* 物件(如程式碼),則JVM會建立多個鎖,不存在鎖爭搶的情況,程式碼中建立了兩個例項變數,每個執行緒訪問自己的例項變數,所以不加synchronized
* 關鍵字都是執行緒安全的。
*
*
*/
class HasSeifPrivateNumT214{
private int num=0;
public void addI(String usrname){
try {
if(usrname.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(usrname+"name="+num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MyThreadAT214 extends Thread{
private HasSeifPrivateNumT214 numRef;
public MyThreadAT214(HasSeifPrivateNumT214 numRef){
super();
this.numRef=numRef;
}
@Override
public void run() {
super.run();
numRef.addI("a");
}
}
class MyThreadBT214 extends Thread{
private HasSeifPrivateNumT214 numT214;
public MyThreadBT214(HasSeifPrivateNumT214 numT214){
super();
this.numT214=numT214;
}
@Override
public void run() {
super.run();
numT214.addI("b");
}
}
/**
* 執行
*/
class RunT214 {
public RunT214(){
HasSeifPrivateNumT214 numT214=new HasSeifPrivateNumT214();
HasSeifPrivateNumT214 numT2141=new HasSeifPrivateNumT214();
MyThreadAT214 at214=new MyThreadAT214(numT214);
at214.start();
MyThreadBT214 bt214=new MyThreadBT214(numT2141);
bt214.start();
}
}
public class T2104 {
public static void main(String[] args) {
RunT214 runT214=new RunT214();
}
}