1. 程式人生 > >面向物件-多執行緒(同步函式的鎖是this與靜態同步函式的鎖是class)

面向物件-多執行緒(同步函式的鎖是this與靜態同步函式的鎖是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可以用來臨時加入執行緒執行。