1. 程式人生 > >java學習day23-多執行緒的引入,同步,鎖

java學習day23-多執行緒的引入,同步,鎖


 (2)Java程式的執行原理及JVM的啟動是多執行緒的嗎?
  Java程式的執行原理:
 *   由java命令啟動JVM,JVM啟動就相當於啟動了一個程序。
 *   接著有該程序建立了一個主執行緒去呼叫main方法。
 *
 * 思考題:
 *   jvm虛擬機器的啟動是單執行緒的還是多執行緒的?
 *    多執行緒的。
 *    原因是垃圾回收執行緒也要先啟動,否則很容易會出現記憶體溢位。
 *    現在的垃圾回收執行緒加上前面的主執行緒,最低啟動了兩個執行緒,所以,jvm的啟動其實是多執行緒的。

 (3)多執行緒的實現方案(自己補齊步驟及程式碼 掌握)
  A:繼承Thread類
  * 方式1:繼承Thread類。
 * 步驟
 *   a:自定義類MyThread繼承Thread類。
 *   b:MyThread類裡面重寫run()?
 *    為什麼是run()方法呢?
                 不是類中的所有程式碼都需要被執行緒執行的。
 *               而這個時候,為了區分哪些程式碼能夠被執行緒執行,java提供了Thread類中的run()用來包含那些被執行緒執行的程式碼。
 *   c:建立物件
 *   d:啟動執行緒
 ------
  如何獲取執行緒物件的名稱呢?
 * public final String getName():獲取執行緒的名稱。
 * 如何設定執行緒物件的名稱呢?
 * public final void setName(String name):設定執行緒的名稱
 *
 * 針對不是Thread類的子類中如何獲取執行緒物件名稱呢?
 * public static Thread currentThread():返回當前正在執行的執行緒物件
 * Thread.currentThread().getName()
 -------
  * public final void setDaemon(boolean on):將該執行緒標記為守護執行緒或使用者執行緒。
 * 當正在執行的執行緒都是守護執行緒時,Java 虛擬機器退出。 該方法必須在啟動執行緒前呼叫。
 *
 * 遊戲:坦克大戰。

 --------
  B:實現Runnable介面
  * 方式2:實現Runnable介面
 * 步驟:
 *   a:自定義類MyRunnable實現Runnable介面
 *   b:重寫run()方法
 *   c:建立MyRunnable類的物件
 *   d:建立Thread類的物件,並把C步驟的物件作為構造引數傳遞
 -------
 (4)執行緒的排程和優先順序問題
  A:執行緒的排程
   a:分時排程
   b:搶佔式排程 (Java採用的是該排程方式)
  B:獲取和設定執行緒優先順序
   a:預設是5
   b:範圍是1-10
   --------
    我們的執行緒沒有設定優先順序,肯定有預設優先順序。
 * 那麼,預設優先順序是多少呢?
 * 如何獲取執行緒物件的優先順序?
 *   public final int getPriority():返回執行緒物件的優先順序
 * 如何設定執行緒物件的優先順序呢?
 *   public final void setPriority(int newPriority):更改執行緒的優先順序。
 *
 * 注意:
 *   執行緒預設優先順序是5。
 *   執行緒優先順序的範圍是:1-10。
 *   執行緒優先順序高僅僅表示執行緒獲取的 CPU時間片的機率高,但是要在次數比較多,或者多次執行的時候才能看到比較好的效果。
 *   
 * IllegalArgumentException:非法引數異常。
 * 丟擲的異常表明向方法傳遞了一個不合法或不正確的引數。

 -------
 (5)執行緒的控制(常見方法)
  A:休眠執行緒
 *  public static void sleep(long millis)
  B:加入執行緒
  public final void join():等待該執行緒終止。
  C:禮讓執行緒
  D:後臺執行緒
  E:終止執行緒(掌握)
   public static void yield():暫停當前正在執行的執行緒物件,並執行其他執行緒。
 * 讓多個執行緒的執行更和諧,但是不能靠它保證一人一次。
 (6)執行緒的生命週期(參照 執行緒生命週期圖解.bmp)
  A:新建
  B:就緒
  C:執行
  D:阻塞
  E:死亡
 (7)電影院賣票程式的實現
  A:繼承Thread類
  B:實現Runnable介面
 (8)電影院賣票程式出問題
  A:為了更符合真實的場景,加入了休眠100毫秒。
  B:賣票問題
   a:同票多次
   b:負數票
 (9)多執行緒安全問題的原因(也是我們以後判斷一個程式是否有執行緒安全問題的依據)
  A:是否有多執行緒環境
  B:是否有共享資料
  C:是否有多條語句操作共享資料
  --------
  如何解決執行緒安全問題呢?
 *
 * 要想解決問題,就要知道哪些原因會導致出問題:(而且這些原因也是以後我們判斷一個程式是否會有執行緒安全問題的標準)
 * A:是否是多執行緒環境
 * B:是否有共享資料
 * C:是否有多條語句操作共享資料
 *
 * 我們來回想一下我們的程式有沒有上面的問題呢?
 * A:是否是多執行緒環境 是
 * B:是否有共享資料 是
 * C:是否有多條語句操作共享資料 是
 *
 * 由此可見我們的程式出現問題是正常的,因為它滿足出問題的條件。
 * 接下來才是我們要想想如何解決問題呢?
 * A和B的問題我們改變不了,我們只能想辦法去把C改變一下。
 * 思想:
 *   把多條語句操作共享資料的程式碼給包成一個整體,讓某個執行緒在執行的時候,別人不能來執行。
 * 問題是我們不知道怎麼包啊?其實我也不知道,但是Java給我們提供了:同步機制。
 *
 * 同步程式碼塊:
 *   synchronized(物件){
 *    需要同步的程式碼;
 *   }
 *
 *   A:物件是什麼呢?
 *    我們可以隨便建立一個物件試試。
 *   B:需要同步的程式碼是哪些呢?
 *    把多條語句操作共享資料的程式碼的部分給包起來
 *
 *   注意:
 *    同步可以解決安全問題的根本原因就在那個物件上。該物件如同鎖的功能。
 *    多個執行緒必須是同一把鎖。

 --------
 (10)同步解決執行緒安全問題
  A:同步程式碼塊
   synchronized(物件) {
    需要被同步的程式碼;
   }
   
   這裡的鎖物件可以是任意物件。
   
  B:同步方法
   把同步加在方法上。
   
   這裡的鎖物件是this
   
  C:靜態同步方法
   把同步加在方法上。
   
   這裡的鎖物件是當前類的位元組碼檔案物件(反射再講位元組碼檔案物件)
 (11)回顧以前的執行緒安全的類
  A:StringBuffer
  B:Vector
  C:Hashtable
  D:如何把一個執行緒不安全的集合類變成一個執行緒安全的集合類
   用Collections工具類的方法即可。
   ----
   // 執行緒安全的類
  StringBuffer sb = new StringBuffer();
  Vector<String> v = new Vector<String>();
  Hashtable<String, String> h = new Hashtable<String, String>();