黑馬程序員--Java學習日記之總結複習(多線程和設計模式)


                                                                      ------Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! -------

一,進程和線程的概念: 
  要了解"線程",必須先了解一下"進程": 
  什麼是進程:
  1.對於"操作系統"而言,每個獨立運行的程序就是獨立的"進程";
  2."操作系統"會分別針對每個"進程"分配一塊獨立的內存空間;
  --什麼是多進程:
  1."操作系統"可以同時維護多個"應用程序"的執行。
  2.每個應用程序都交由操作系統管理,在某個時間點上,會有一個應用程序被操作系統分配給CPU去執行,執行一會後,會被操作系統
         終止執行,並交由另一個"應用程序"繼續執行。由於轉換非常快,CPU的運算速度也非常快,這就讓我們感覺好像是多個應用程序在
         同時執行一樣。
       3.多進程的意義:
      1).方便了我們用戶的使用。我們可以同時啓動多個程序,一邊聽歌,一邊上網,一邊下載;
        2).充分的利用CPU資源;
  什麼是線程:
  1.線程是由一個"進程"的內部啓動的,可以脫離於"主進程"而獨立運行的一塊代碼;
  2.一個線程一旦啓動,將和"主進程"並行運行,一起面對操作系統,搶佔系統資源;
  3.一個"進程"可以啓動多個"線程";
  --什麼是多線程:
  1.一個進程可以同時啓動多個線程去單獨運行;這個程序就是一個多線程程序;
  2.多線程的意義:
  1).可以使我們的應用程序"同時"運行多個非常複雜的代碼;
  2).使我們的程序不用等待那些代碼的執行完畢,就可以繼續獲得執行;
  3).充分的利用了CPU的資源;
  
  什麼是"並行"和"併發":
  1."並行"是指邏輯上一起在執行,它強調的是在"同一段時間內"一起運行的程序;
  2."併發"是指物理上的搶佔同一資源。它強調的是在"同一時刻時"一起搶佔系統的某個共享資源;
二, 實現線程的:
                                                                                                                                方式一
  實現步驟:

  1.自定義一個線程類,要繼承自Thread;
  2.重寫Thread中的run()方法;將要在線程中執行的代碼寫到這裏;
  3.啓動線程:
  1).實例化一個我們自定義的線程類;
  2).調用它的start()方法;啓動線程;
 public class Demo {  
02.    public static void main(String[] args) {  
03.        MyThread t1 = new MyThread();  
04.        MyThread t2 = new MyThread();  
05.          
06.    //  t1.run();//相當於普通的方法調用,不是啓動一個線程  
07.    //  t2.run();//相當於普通的方法調用,不是啓動一個線程  
08.          
09.        t1.start();  
10.        t2.start();  
11.          
12.        for(int i = 0;i < 100;i++){  
13.            System.out.println("主進程 i = " + i);  
14.        }  
15.          
16.        //嘗試再次啓動t1  
17.    //  t1.start();//運行時異常。不能多次調用start(),否則拋出異常:java.lang.IllegalThreadStateException  
18.    }  
19.}  


  
   注意:
  1.一個線程類,可以實例化多個對象,並分別啓動。也就意味着多個線程同時運行;
  2.一個線程對象,只能調用一次start,不能重複調用。否則拋出異常:java.lang.IllegalThreadStateException

  3.只用調用start()纔是啓動線程。run()方法內的代碼會以一個線程的方式去運行;

一.線程實現方式:
 1.繼承Thread類;
 2.實現Runnable接口;

二.設置獲取線程的名稱:
 getName()和setName(String name);
三.設置獲取線程的優先級:
 getPriority()和setPriority(int n);
 線程的優先級範圍:1--10(從低到高)
四.線程的休眠:sleep(long m):休眠到指定的m毫秒後,將自動醒來;
   加入:join();
   禮讓:yield():退回到"就緒狀態",可能會被操作系統重新分配;
   守護:setDaemon(boolean on):on爲true,守護線程。主進程結束,守護線程也結束,但不會立即結束,會有一個小緩衝;
   中斷:stop()(過時了)
         interrupt():線程一定要處於:Object-->wait();Thread-->sleep();Thread--join()三種狀態之一時,才能觸發此異常;
五.解決併發性問題:
 1.使用關鍵字:synchronized
 2.synchronized可以修飾一個代碼塊:同步代碼塊
          synchronized可以修飾一個方法:同步方法
 3.靜態的方法可以被synchronized修飾。
          靜態的方法內部也可以包含synchronized的代碼塊,但一般鎖定是某個類的class對象。

一.JDK5的Lock鎖:
 Lock lock = ....;
 lock.lock();
 try{
  //需要同步的代碼
 }finally{
  lock.unlock();
 }
二.死鎖的現象:
 見圖
三.生產和消費者問題:
 1.單生產和單消費;
 2.在共享資源中:
  1).wait():讓訪問的線程等待(釋放鎖)
  2).notify()和notifyAll():喚醒;
四.線程組:
 1.任何的線程都有一個默認的線程組;
 2.可以自行指定線程組:
  1).實例化一個線程組;
  2).通過Thread的構造方法去指定線程組;
 3.可以統一對線程組內的所有線程執行統一操作;
五.線程池:JDK5後出現:
 1.Executors類的
  public static ExecutorService newCachedThreadPool()
  public static ExecutorService newFixedThreadPool(int nThreads)
  public static ExecutorService newSingleThreadExecutor()
 2.調用ExecutorService的:
  Future<?> submit(Runnable task)
   <T> Future<T> submit(Callable<T> task)


 
六.JDK5的多線程的實現方式(多線程實現的方式3)
 1.自定義類,實現Callable接口;
 2.重寫call()方法;(有返回值了)
 3.啓動:
  使用線程組的方式啓動線程;
  
七.定時器:
 1.TimersTask(抽象類):定義任務
  1).自定義類,繼承自TimerTask;
  2).重寫run()方法;
 2.Timer類:
  構造方法:Timer();
  執行任務:
  public void schedule(TimerTask task, long delay):在delay毫秒後執行一次;
  public void schedule(TimerTask task,long delay,long period):在delay毫秒後開始執行,並每間隔period毫秒後會重複執行;

八.設計模式:
 1.簡單工廠模式:
  1.定義具體產品類;
  2.定義工廠類;
  3.在工廠類中提供針對每個產品的get方法,或者提供一個方法獲取所有產品;
  優點:前端無需直接面對具體的產品,只需要通過工廠獲取具體產品就可以;
  缺點:每增加一個新產品,都要修改工廠類;
 2.工廠方法模式:
  1.定義產品的接口;
  2.定義工廠的接口;
  3.增加一個產品時,定義產品類,實現"產品接口",定義工廠類,實現"工廠接口"。
  優點:新增產品時,對原類無需任何修改;
  缺點:類太多;
 3.單例模式--餓漢式:
  class Student{
   prviate static Student stu = new Student();
   private Student(){
   }
   public static Student getStudent(){
    return stu;
   }
  }
 4.單例模式--懶漢式:
  class Student{
   private static Student stu = null;
   private Student(){
   }
   public synchronized static Student getStudent(){
    if(stu == null){
     stu = new Student();
    }
    return stu;
   }
  }

有時候我們還需要結合interrupt()方法來結束一個線程,見如下例子:
package com.heima.exam;

class StopThreadTest {
 public static void main(String[] args) {
  
  ThreadInStop t1 = new ThreadInStop();
  t1.start();
  int index = 0;
  
  while(true) {
   if(index++ == 500){
    t1.stopThread();
    t1.interrupt();
    break;
   }
   System.out.println(Thread.currentThread().getName());
  }
  System.out.println("main() exit");
 }
}

class ThreadInStop extends Thread {
 
 private boolean bStop = false;
 
 public synchronized void run() {
  
  while(!bStop) {
   try {
    wait();
   } catch(InterruptedException e) {
    if(bStop) {
     return;
    }
   }
   System.out.println(getName());
  }
 }
 
 public void stopThread() {
  bStop = true;
 }
}





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