面向物件-多執行緒(同步函式的鎖是this與靜態同步函式的鎖是class)
阿新 • • 發佈:2019-02-19
同步函式使用的是哪一個鎖呢?
函式需要被物件呼叫,那麼函式都有一個所屬物件引用,就是this。。
通過驗證,發現不在是this,因為靜態方法中不可以定義this。
靜態進記憶體:記憶體中沒有本類物件,但是一定有該類對應的位元組碼檔案物件。
類名.class 該類物件的型別是Class
函式需要被物件呼叫,那麼函式都有一個所屬物件引用,就是this。。
所以同步函式使用的鎖是this。
程式碼:
如果同步函式被靜態修飾後,使用的鎖是什麼呢?class Demo implements Runnable { private int t=200; Object obj = new Object(); boolean flag = true; public void run () { if(flag) {//同步程式碼塊 while(true) { synchronized (this) { if(t>0) { try {Thread.sleep(10);} catch (Exception e) {} System.out.println(Thread.currentThread().getName()+"-code:"+t--); } } } } else {//同步函式 while(true) show(); } } public synchronized void show() {//this if(t>0) { try {Thread.sleep(10);} catch (Exception e) {} System.out.println(Thread.currentThread().getName()+"--show:"+t--); } } } public class code { public static void main(String[] args) { Demo t = new Demo(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); t1.start(); try {Thread.sleep(10);} catch (Exception e) {} t.flag = false; t2.start(); } }
通過驗證,發現不在是this,因為靜態方法中不可以定義this。
靜態進記憶體:記憶體中沒有本類物件,但是一定有該類對應的位元組碼檔案物件。
類名.class 該類物件的型別是Class
靜態的同步方法:使用的鎖是該方法所在類的位元組碼檔案物件。 類名.class 位元組碼檔案物件是唯一的。
用static修飾->物件在方法區中
不用static修飾->物件在堆記憶體中
程式碼:
class Demo implements Runnable { private static int t=200; boolean flag = true; public void run () { if(flag) { while(true) { synchronized (Demo.class) { if(t>0) { try {Thread.sleep(10);} catch (Exception e) {} System.out.println(Thread.currentThread().getName()+"-code:"+t--); } } } } else { while(true) show(); } } public static synchronized void show() {//class if(t>0) { try {Thread.sleep(10);} catch (Exception e) {} System.out.println(Thread.currentThread().getName()+"--show:"+t--); } } } public class code { public static void main(String[] args) { Demo t = new Demo(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); t1.start(); try {Thread.sleep(10);} catch (Exception e) {} t.flag = false; t2.start(); } }
死鎖:同步中巢狀同步,鎖不同。
Jion:當執行緒執行到了B執行緒的 .join()方法時,A就會等待。等B執行緒都執行完,A才會執行。
join可以用來臨時加入執行緒執行。