關於多線程的問題

1>多線程的 實現方式     繼承Thread類    或者      實現 Runnable  接口

2>出現線程安全的原因(主要講解 同步鎖)

    線程  操作共性數據的多條代碼 分開執行,就會引起線程安全問題(關鍵點:存在共性數據操作共性數據的多條代碼被分開

    解決方案:保證     操作共性數據的多條代碼在同一時間段內 只有一個線程在執行,執行期間,不允許其他線程進入。

    解決問題的方式:
    java提供瞭解決方案,就是同步機制。
    代碼體現:同步代碼塊。
    synchronized(對象)//對象可以是任意對象。
    {
        需要被同步封裝的語句。
    }

    同步的好處:
    解決了多線程的安全問題。

同步前提:
    1,必須要有兩個或者兩個以上的線程。
    2,多個線程必須使用同一個鎖。

同步的弊端:
    降低運行效率,對資源是一種消耗。

class Ticket implements Runnable{
	private int tickets = 10;
	private Object obj = new Object();
	public void run(){
		while(tickets > 0){
			try {
				synchronized(obj){
					Thread.sleep(100);
					if(tickets>0)
						System.out.println(Thread.currentThread().getName()+"   "+tickets--);
				}
			} catch (InterruptedException e) {
				throw new RuntimeException();
			}
		}
	}
}


public class TicketDemo {
	public static void main(String[] args) {
		Ticket t = new Ticket();
		
		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
		Thread t3 = new Thread(t);
		Thread t4 = new Thread(t);
		
		t1.start();
		t2.start();
		t3.start();
		t4.start();
		
	}
}

將同步代碼塊 提取出來 封裝爲一個方法,同時在該方法 同步(添加synchronized關鍵字),於是就出現了同步函數。


同步代碼塊的鎖 是 private Object obj = new Object();

同步函數用的鎖 是 this


同步函數和同步代碼塊的區別:
    同步函數使用的鎖是固定的 this。
    同步代碼塊可以指定任意的對象作爲鎖。
    一般開發常用同步代碼塊。


靜態同步函數鎖使用的鎖是:所屬類的字節碼文件對象 寫法 類名.class


驗證 使用的 鎖 是什麼的  方法如下,將同步代碼塊的鎖 

class Ticket implements Runnable
{
	private  int ticks = 100;
	Object obj = new Object();
	boolean flag = true;
	public  void run()
	{
		if(flag)	
			while(true)
			{
				synchronized(this)
				{
					if(ticks>0)
					{	
						try{Thread.sleep(10);}catch(InterruptedException e){}
						System.out.println(Thread.currentThread().getName()+"..code.."+ticks--);
					}
				}
			}
		else
			while(true)
				show();
	}
	public synchronized void show()
	{
		if(ticks>0)
		{
			try{Thread.sleep(10);}catch(InterruptedException e){}
			System.out.println(Thread.currentThread().getName()+"..show funciton.."+ticks--);
		}
	}

}


class ThisLockDemo
{
	public static void main(String[] args) 
	{
		Ticket t = new Ticket();

		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);

		t1.start();
		try{Thread.sleep(10);}catch(Exception e){}
		t.flag = false;
		t2.start();
	}
}



3>關於  死鎖的 一個例子

class DeadLock implements Runnable{

	private static Object lockA = new Object();
	private static Object lockB = new Object();
	private boolean flag;
	DeadLock(boolean flag){
		this.flag = flag;
	}
	
	public void run() {
		if(flag){
			while(true){
				synchronized (lockA) {
					System.out.println("   if ------- lockA       ");
					synchronized (lockB) {
						System.out.println("   if ------- lockB       ");
					}
				}
			}
		}else{
			while(true){
				synchronized (lockB) {
					System.out.println("   else ------- lockB       ");
					synchronized (lockA) {
						System.out.println("   else ------- lockA       ");
					}
				}
			}
		}
	}
	
}


public class DeadLockDemo {
	public static void main(String[] args) {
		DeadLock t1 = new DeadLock(true);
		DeadLock t2 = new DeadLock(false);
		
		Thread tt1 = new Thread(t1);
		Thread tt2 = new Thread(t2);
		tt1.start();
		tt2.start();
		
	}
}

注意上面代碼中使用的鎖,是static的,保證t1和t2使用的是相同的   lockA和lockB


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章