示例002
package com.bjsxt.base.sync002;
/**
* 關鍵字synchronized取得的鎖都是對象鎖,而不是把一段代碼(方法)當作鎖,
* 因此代碼中哪一個線程先執行synchronized關鍵字的方法,哪一個線程就持有該方法所屬對象的鎖(Lock),
*
* 在靜態方法上加synchronized關鍵字,表示鎖定.class類,類一級別的鎖(獨佔.class類)。
* @author alienware
*
*/
public class MultiThread {
//Cannot make a static reference to the non-static field num
//private int num = 0;
/** static */
public static synchronized void printNum(String tag){
try {
int num = 0;
if(tag.equals("a")){
num = 100;
System.out.println("tag a, set num over!");
Thread.sleep(1000);
} else {
num = 200;
System.out.println("tag b, set num over!");
}
System.out.println("tag " + tag + ", num = " + num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//注意觀察run方法輸出順序
public static void main(String[] args) {
//倆個不一樣的對象
final MultiThread m1 = new MultiThread();
final MultiThread m2 = new MultiThread();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m1.printNum("a");
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
m2.printNum("b");
}
});
t1.start();
t2.start();
}
}
不帶synchronized的輸出
tag a, set num over!
tag b, set num over!
tag b, num = 200
tag a, num = 100
帶synchronized的輸出
tag a, set num over!
tag a, num = 100
tag b, set num over!
tag b, num = 200
示例003
package com.bjsxt.base.sync003;
/**
* 對象鎖的同步和異步問題
* @author alienware
*
*/
public class MyObject {
public synchronized void method1(){
try {
System.out.println(Thread.currentThread().getName());
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/** synchronized */
public void method2(){
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
final MyObject mo = new MyObject();
/**
* 分析:
* t1線程先持有object對象的Lock鎖,t2線程能夠以異步的方式調用對象中的非synchronized修飾的方法,而無需等待
* t1線程先持有object對象的Lock鎖,t2線程若是在這個時候調用對象中的同步(synchronized)方法則需等待,也就是同步
*/
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
mo.method1();
}
},"t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
mo.method2();
}
},"t2");
t1.start();
t2.start();
}
}