同步代碼塊、靜態同步方法、非靜態同步方法的鎖分別是:
- 同步代碼塊可使用自定義的Object對象,也可使用this或者當前類的字節碼文件(類名.class);
- 靜態同步方法的鎖是當前類的字節碼文件(類名.class);
- 非靜態同步方法的鎖是this;
證實方法:
- 兩個線程之間實現同步,一個線程使用同步代碼塊,一個線程使用同步方法。
- 若是這兩個線程同步了,說明了使用的是同一個鎖;
建立線程類(以售票爲例)
/**
* @methodDesc 售票線程類
*/
public class ThreadTrain extends Thread {
// 總共又100張
private static int trainCount = 100;
protected static boolean flag = true;
@Override
public void run() {
while (trainCount > 0) {
if (flag) { // 執行同步代碼塊,this鎖
System.out.println("flag==="+flag);
// 出售火車票
sale1();
}else {
System.out.println("flag==="+flag);
// 出售火車票
sale11();
}
flag = !flag;
}
}
// 同步代碼塊
public void sale1() {
// 同步代碼塊,包裹須要解決線程安全問題的代碼塊,兩個線程同時訪問
synchronized (this) { // 只能有一個線程進行訪問,必須拿到鎖的時候才能訪問
if (trainCount > 0) { // 不加判斷,會出現出售第101張票的狀況
System.out.println(Thread.currentThread().getName() + ", 出售第" + (100 - trainCount + 1) + "張票");
trainCount--;
}
}
}
// 靜態同步代碼塊
public void sale2() {
// 同步代碼塊,包裹須要解決線程安全問題的代碼塊,兩個線程同時訪問
synchronized (ThreadTrain.class) { // 只能有一個線程進行訪問,必須拿到鎖的時候才能訪問
if (trainCount > 0) { // 不加判斷,會出現出售第101張票的狀況
System.out.println(Thread.currentThread().getName() + ", 出售第" + (100 - trainCount + 1) + "張票");
trainCount--;
}
}
}
// 同步方法
public synchronized void sale11() {
if (trainCount > 0) { // 不加判斷,會出現出售第101張票的狀況
System.out.println(Thread.currentThread().getName() + ", 出售第" + (100 - trainCount + 1) + "張票");
trainCount--;
}
}
// 靜態同步方法
public static synchronized void sale22() {
if (trainCount > 0) { // 不加判斷,會出現出售第101張票的狀況
System.out.println(Thread.currentThread().getName() + ", 出售第" + (100 - trainCount + 1) + "張票");
trainCount--;
}
}
}
建立測試類
/**
* @methodDesc 多線程模擬售票問題
*/
public class ThreadDemo {
public static void main(String[] args) throws InterruptedException {
// 建立售票線程對象
ThreadTrain train1 = new ThreadTrain();
// 建立多個售票窗口,並給其取別名
Thread t1 = new Thread(train1, "窗口1");
Thread t2 = new Thread(train1, "窗口2");
t1.start();
t2.start();
}
}
驗證方法
public void run() {
while (trainCount > 0) {
if (flag) { // 執行同步代碼塊,this鎖
System.out.println("flag==="+flag);
// 出售火車票
sale1();
}else {
System.out.println("flag==="+flag);
// 出售火車票
sale11();
}
flag = !flag;
}
}
public void run() {
while (trainCount > 0) {
if (flag) { // 執行同步代碼塊,this鎖
System.out.println("flag==="+flag);
// 出售火車票
sale2();
}else {
System.out.println("flag==="+flag);
// 出售火車票
sale22();
}
flag = !flag;
}
}