黑馬程序員_多線程學習日誌

---------------------- android培訓 、 java培訓 、 期待與您交流! ----------------------


1、 多線程中的概念:

        a. 進程:正在進行中的程序(直譯),其實就是該應用程序在內存中分配的空間。
        b. 線程:是在進程中負責程序執行的路徑。負責程序執行的。
                在進程中至少有一個線程在執行。

2、什麼是多線程?

        當有多部分代碼需要同時運行時,就需要開闢多條執行路徑來完成。這時該程序就是多線程程序。

        多線程解決了:讓多部門門代碼同時運行的問題

3、JVM中的多線程瞭解

        jvm中也一樣是多線程程序,只要有一個程序負責程序執行,又有一個線程負責着垃圾回收,這個就是同時進行的。

        結論:每一個線程都有自己的運行代碼,這個稱之爲線程的任務。

        對於每一個線程便於識別都有自己的名稱,比如負責主函數執行程序代碼的線程,稱之爲 主線程,main thread。
        主線程運行的代碼都定義在主函數中。
        負責回收垃圾的線程:垃圾回收線程。
        發現運行結果不一致:多線程的隨機性構成的。因爲cpu的快速切換的原因。

4、 調用run和調用start的區別?

	class Demo extends Thread
	{
		private String name;
		Demo(String name)
		{
			this.name = name;
		}
		public void run()
		{
			for(int x=0; x<10; x++)
			{
				System.out.println("name...."+x+"....."+name);
			}
		}
	}
	class ThreadDemo 
	{
		public static void main(String[] args) 
		{
			//創建線程對象。
			Demo d1 = new Demo("小強");
			Demo d2 = new Demo("旺財");

			//開啓線程。讓線程運行起來。
			d1.start();
			d2.start();

			d1.run();
			d2.run();
		}
	}

區別:start():開啓線程的同時,調用run()方法!
           run():只是在調用run方法,沒有開啓線程!

5、第一種創建線程的方法:繼承Thread類,並複寫run方法。

        每一個線程都應該有自己的任務,而且任務都會定義在指定的位置上。
        主線程的任務都定義在main方法中。
        自定義線程的任務都定義在了run方法中。

        Thread t = new Thread();
        t.start();//這種開啓只能調用Thread類中自己的run方法。而該run方法中並未定義自定義的內容。

        我還需要創建線程,還要讓線程執行自定義的任務。
        所以可以複寫run方法。前提必須是繼承Thread類。

        而繼承了Thread後,該子類對象就是線程對象。

6、第二種創建線程的方法:
        1.實現Runnable接口。
        2.覆蓋run方法。
        3.通過Thread類創建線程對象。

        4.將Runnable接口的子類對象作爲實參傳遞給Thread類中的構造函數。

        5.調用start方法開啓線程,並運行Runnable接口子類的run方法。

       第二種實現Runnable接口創建線程的思想:
        將線程任務和線程對象進行解耦,將線程任務單獨封裝成對象。另,實現Runnable接口可以避免單繼承的侷限性。
        所以建議創建多線程,都是用實現Runnable接口方法。
        任務對象實現規則,線程對象在使用規則。

7、 線程安全問題:
        原因:  1.多線程在同時處理共享數據;
                    2.線程任務中有多條代碼在操作共享數據。

        安全問題成因就是:一個線程在通過多條操作共享數據的過程中,其他線程參與了共享數據的操作,導致了數據的錯誤。

        想要知道你的多線程程序有沒有安全問題:只要看線程任務中是否有多條代碼在處理共享數據。

        解決:一個線程在通過多條語句操作共享數據的過程中,不允許其他線程參與運算。

        Java中提供了同步代碼塊進行引起安全問題的代碼封裝。(同步)

8、 同步:
        格式:
        synchronized(對象)
        {
               //需要被同步的代碼;
        }

        同步:
               好處:解決了多線程的安全問題;
               弊端:降低了多線程的效率。

        同步的前提:
        1.至少有兩個線程在同步中;
        2.必須保證同步使用的是一個鎖;

9、 同步的第二種表現形式:

        同步函數。

        問題:同步函數使用的鎖是神什麼?this

10、 同步函數和同步代碼塊的區別?

        同步函數使用的固定鎖this

        同步代碼塊使用的鎖是可以指定的

11、 靜態同步函數鎖是什麼?

        就是所在類的 類名.class 字節碼文件對象。

12、 單例設計模式:懶漢式中加雙重判斷既提高了效率,有增加了安全。

13、 同步的另一個弊端:
        容易引發死鎖。
        開發時儘量避免同步嵌套的情況。

        死鎖演示:

/*
寫一個多線程嵌套的死鎖演示,死鎖就是當兩個鎖同時開啓後,相互爭奪鎖對象而導致的;
*/
class Demo implements Runnable
{
	private boolean flag;

	Demo(boolean flag)
	{
		this.flag=flag;
	}
	public void run()
	{
		while(true)
		{
			if(flag)
			{
				synchronized(MyLock.LOCKA)//LOCKA鎖
				{
					System.out.println("if locka");
					synchronized(MyLock.LOCKB)//LOCKA鎖中嵌套的LOCKB鎖
					{
						System.out.println("if lockb");
					}
				}
			}
			else
			{
				synchronized(MyLock.LOCKB)//LOCKB鎖
				{
					System.out.println("else lockb");
					synchronized(MyLock.LOCKA)//LOCKB鎖中嵌套的LOCKA鎖
					{
						System.out.println("else locka");
					}
				}
			}
		}
	}
}
class MyLock//定義兩個鎖對象
{
	public static final Object LOCKA=new Object();
	public static final Object LOCKB=new Object();
}
class DeadLockDemo
{
	public static void main(String[] args) 
	{
		/*
		創建兩個線程任務,開啓兩個線程
		*/
		Demo d1=new Demo(true);
		Demo d2=new Demo(false);
		Thread t1=new Thread(d1);
		Thread t2=new Thread(d2);
		t1.start();
		t2.start();
	}
}

14、 多線程間通信:多個線程處理同一資源,但是處理動作卻不同。

        wait(); 可以讓當前線程處於等待,這時的線程被臨時存儲到了線程池中 ;
   
        notify();喚醒線程池中任意一個等待的線程。

        notifyAll();喚醒線程池中所有的等待線程。

        這些方法在使用時,必須定義在同步中,必須被所屬同步的鎖調用。
    
15、 單生產者、單消費者:等待喚醒機制。

16、 多生產者,多消費者:

17、 sleep和wait的區別?

        sleep必須指定時間,wait可以指定可以不指定。

        sleep和wait都可以讓線程處於凍結狀態,釋放執行權

        持有鎖的線程執行sleep,,不釋放鎖,持有鎖的線程執行到wait釋放鎖。
        sleep到時間會自動醒,wait沒有指定時間,只能被其他線程通過notify喚醒。

------------------------------------------------------------------------

        Lock lock=new ReentrantLock();創建互斥鎖

        await();等待

        signal();喚醒

        signalAll();喚醒所有
    

---------------------- android培訓 、 java培訓 、 期待與您交流! ----------------------
詳細請查看:www.itheima.com
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章