java多執行緒詳解四 驗證同步函式的鎖是this
阿新 • • 發佈:2019-01-24
驗證同步函式的鎖是this
/** * Created by Perk on 2016/7/17. */ class Ticket implements Runnable { private int num = 200; Object object = new Object(); boolean flag = true; @Override public void run() { if (flag) { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (obj) { if (num > 0) { System.out.println(num + ":" + Thread.currentThread().getName() + "synblock"); num--; } } } } else { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } show(); } } } public synchronized void show() { if (num > 0) { System.out.println(num + ":" + Thread.currentThread().getName() + "function"); num--; } } }
public class TicketDemo { public static void main(String[] args) { Ticket ticket1=new Ticket(); Thread thread1=new Thread(ticket1); Thread thread2=new Thread(ticket1); thread1.start(); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } ticket1.flag=false; thread2.start(); } }
通過設定flag 使兩個執行緒分別執行同步程式碼塊和同步函式的程式碼。
synchronized (this) {
if (num > 0) {
System.out.println(num + ":" + Thread.currentThread().getName() + "synblock");
num--;
}
}
將同步程式碼塊的鎖換成this.發現同步安全問題解決了,所有同步函式使用的同步鎖是this.
如果在同步函式上加上static關鍵字則又會出現同步安全問題。
public static synchronized void show() { if (num > 0) { System.out.println(num + ":" + Thread.currentThread().getName() + "function"); num--; } }
將同步程式碼塊的鎖設為this.getClass()或 Ticket.class可以解決同步安全問題
synchronized (this.getClass()) { //Ticket.class
if (num > 0) {
System.out.println(num + ":" + Thread.currentThread().getName() + "synblock");
num--;
}
}