線程同步和死鎖(傳智播客)

一.同步
多線程在操作共享資源時,某一時刻只能有一個線程操作共享資源。
1.同步代碼塊

public class MyThread implements Runnable{
	
	private int num = 400;
	Object obj = new Object();
	/* (non-Javadoc)
	 * @see java.lang.Thread#run()
	 */
	@Override
	public void run() {
		while(true){
			synchronized(obj){
				if(num>0){
					System.out.println(Thread.currentThread().getName()+"...is saling..."+num);;
					num--;
				}
			}
		}
	}

	public static void main(String[] args) {
		MyThread my = new MyThread();
		Thread t0 = new Thread(my);
		Thread t1 = new Thread(my);
		t0.start();
		t1.start();	
	}
}

2.同步方法

public class MyThread implements Runnable{
	
	private int num = 400;

	@Override
	public void run() {
		while(true){
			fun();
		}
	}
	
	public synchronized void fun(){
		if(num>0){
			System.out.println(Thread.currentThread().getName()+"...is saling..."+num);;
			num--;
		}
	}
	
	public static void main(String[] args) {
		MyThread my = new MyThread();
		Thread t0 = new Thread(my);
		Thread t1 = new Thread(my);
		t0.start();
		t1.start();	
	}
}

3.兩者的區別

  • 同步代碼塊的鎖是任意的,同步方法的鎖是固定的, 靜態同步方法的鎖是該方法所屬的對象(當前類運行時對象)。
  • 同步的前提是必須有多個線程使用同一個鎖。
  • 判斷鎖的狀態,會消耗系統資源從而導致程序的效率低。

二.死鎖
1.什麼是死鎖
指多個線程競爭資源導致互相等待的僵局,如果沒有外力的作用,這種現象將一直持續下去。
2.產生的條件

  • 互斥:指共享資源在某一時刻只能被一個線程所佔有,具有排他性。
  • 不剝奪:指被線程所佔有的資源不能被其它線程強行奪走,除非自己釋放。
  • 保持和請求:請求新資源的線程在佔有一個資源的情況下,處於阻塞狀態並且不釋放已有的資源。
  • 循壞等待鏈:有這樣一種等待鏈,鏈上的線程所佔有的資源是其它線程正在請求的資源。
    3.實例
public class MyThread implements Runnable{
    boolean flag = true;
    Object chinese = new Object();
    Object american = new Object();
	@Override
	public void run() {
		if(flag){
			while(true){
				synchronized(american){
					System.out.println("...if...american");
					synchronized(chinese){
						System.out.println("...if...chinese");
					}
				}
			}
		}
		else{
			while(true){
				synchronized(chinese){
					System.out.println("...else...chinese");
					synchronized(american){
						System.out.println("...else...american");
					}
				}
			}
		}
	}

	public static void main(String[] args) {
		MyThread my = new MyThread();
		Thread t0 = new Thread(my);
		Thread t1 = new Thread(my);
		t0.start();
		try{
			Thread.sleep(10);
		}catch(InterruptedException e){
			
		}
		my.flag = false;
		t1.start();
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章