JAVAThread 多線程學習

來源:互聯網
上載者:User

JAVAThread 多線程學習

開始第二遍學習java了,發現有好多的知識點在之前學習的時候是不瞭解的。在java多線程的板塊中,學到了除了繼承Thread 實現runnable介面以外 還學到了第三種的基於線程池的實現callable介面的線程方式。感覺java真實博大精深。對java線程的筆記總結:

java線程java程式由一條線程執行完畢 稱為單線程程式java程式由多條程式執行完畢 稱為多線程程式

1:多線程
(1)多線程:一個應用程式有多條執行路徑 進程:正在執行的應用程式 線程:進程的執行單元,執行路徑 單線程:一個應用程式只有一條執行路徑 多線程:一個應用程式有多條執行路徑

    多進程的意義?           提高CPU的使用率    多線程的意義?        提高應用程式的使用率(2)Java程式的運行原理及JVM的啟動是多線程的嗎?    A:Java命令去啟動JVM,JVM會啟動一個進程,該進程會啟動一個主線程。    B:JVM的啟動是多線程的,因為它最低有兩個線程啟動了,主線程和記憶體回收線程。
(3)多線程的實現方案A:繼承Thread類B:實現Runnable介面
* 兩種方式的比較   

(4)線程的調度和優先順序問題A:線程的調度
  • a:分時調度
  • b:搶佔式調度 (Java採用的是該調度方式)
  • B:擷取和設定線程優先順序    a:預設是5    b:範圍是1-10
    (5)線程的控制(常見方法)A:休眠線程API方法:

    線程睡眠毫秒數

    • public static void sleep(long millis)B:加入線程API方法

      join:等待線程終止,等待線程執行完畢後其它的線程才可以運行

      • public final void join();C:礼讓線程API方法

        一定程度上讓多個線程的執行和諧,不靠譜

        • public static void yield()D:後台線程API方法
          • public final void setDaemon(boolean on)
            當正在啟動並執行線程都是守護線程時,java虛擬機器退出,該方法必須線上程啟動之前調用
            標記為守護線程後,線程會依附於某個線程,不會獨立的runE:終止線程(掌握)API方法
            • public final void stop() 讓線程停止,已淘汰

            • public void interrupt() 終止線程,並且拋出InterruptedException異常,並會執行後續的代碼

              線程的生命週期(參照 線程生命週期圖解.bmp)

              A:建立

              建立線程對象的過程<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPGg0PkI6vs3Q9zwvaDQ+CjxwPgrT0Na00NC1xMz1vP66zdfKJiMyNjY4NDujrMO709DWtNDQyKg8L3A+CjxoND5jOtTL0NA8L2g0Pgo8cD4K09DUy9DQtcTXyiYjMjY2ODQ7o6zT0Na00NDIqDwvcD4KPGg0PkQ61+jI+zwvaDQ+CjxwPgrDu9PQ1rTQ0NfKJiMyNjY4NDujrMO709DWtNDQyKg8L3A+CjxoND5FOsvAzfY8L2g0Pgo8cD4Kz9+zzLbUz/Ox5LPJwKy7+KOstci0/bG7u9jK1TwvcD4KPHByZSBjbGFzcz0="brush:java;">(7)電影院賣票程式的實現 A:繼承Thread類 B:實現Runnable介面(8)電影院賣票程式出問題 A:為了更符合真實的情境,加入了休眠100毫秒。 B:賣票問題 a:同票多次 b:負數票(9)多安全執行緒問題的原因(也是我們以後判斷一個程式是否有安全執行緒問題的依據) A:是否有多線程環境 B:是否有共用資料 C:是否有多條語句操作共用資料(10)同步解決安全執行緒問題A:同步代碼塊

              synchronized(對象) {
              需要被同步的代碼;
              }

              這裡的鎖對象可以是任意對象。

              B:同步方法

              把同步加在方法上。

              這裡的鎖對象是this

              C:靜態同步方法

              把同步加在方法上。

              這裡的鎖對象是當前類的位元組碼檔案對象(反射再講位元組碼檔案對象)

              (11)回顧以前的安全執行緒的類
              • A:StringBuffer
              • B:Vector
              • C:Hashtable
              • D:如何把一個線程不安全的集合類變成一個安全執行緒的集合類用Collections工具類的方法即可。
              相關知識點(1)JDK5以後的針對線程的鎖定操作和釋放操作Lock鎖
                  // 定義鎖對象    private Lock lock = new ReentrantLock();    @Override    public void run() {        while (true) {            try {                // 加鎖                lock.lock();                if (tickets > 0) {                    try {                        Thread.sleep(100);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    System.out.println(Thread.currentThread().getName()                            + "正在出售第" + (tickets--) + "張票");                }            } finally {                // 釋放鎖                lock.unlock();            }        }    }
              (2)死結問題的描述和代碼體現
              • 是指兩個或者兩個以上的線程在執行的過程中,因爭奪資源產一種互相等待現象
              • 同步代碼塊的嵌套案例
                  @Overridepublic void run() {    // 死結代碼    if (flag) {        // 同步嵌套        synchronized (MyLock.objA) {            System.out.println("if obja");            synchronized (MyLock.objB) {                System.out.println("if objb");            }        }    } else {        synchronized (MyLock.objB) {            System.out.println("else objb");            synchronized (MyLock.objA) {                System.out.println("else obja");            }        }    }}
              (3)生產者和消費者多線程體現(線程間通訊問題)
                  以學生作為資源來實現的    資源類:Student    設定資料類:SetThread(生產者)    擷取資料類:GetThread(消費者)    測試類別:StudentDemo    代碼:        A:最基本的版本,只有一個資料。        B:改進版本,給出了不同的資料,並加入了同步機制        C:等待喚醒機制改進該程式,讓資料能夠實現依次的出現            wait() 線程等待後立即釋放所持有的鎖,被喚醒後在等待的位置繼續執行            notify() 喚醒並不代表立馬可以執行 線程會轉為就緒狀態 等待下一次執行            notifyAll() (多生產多消費)   
              • 為什麼定義在Object中?
                • 這些方法的調用通過鎖對象調用,而我們使用的鎖可能是任意鎖對象。所以,這些方法必須定義在Object類中 =* 等待喚醒機制的代碼最佳化。把資料及操作都寫在了資源類中(4)線程組
                  • Java中使用ThreadGroup來表示線程組,它可以對一批線程進行分類管理,Java允許程式直接對線程組進行控制。 預設情況下,所有的線程都屬於主線程組(main組)。
                    返回該線程所屬的線程組
                  • public final ThreadGroup getThreadGroup()
                    我們也可以給線程設定分組
                  • Thread(ThreadGroupgroup, Runnabletarget, Stringname)
                    建立線程組代碼:

                        // ThreadGroup(String name)    ThreadGroup tg = new ThreadGroup("這是一個新的組");    MyRunnable my = new MyRunnable();    // Thread(ThreadGroup group, Runnable target, String name)    Thread t1 = new Thread(tg, my, "林青霞");    Thread t2 = new Thread(tg, my, "劉意");    System.out.println(t1.getThreadGroup().getName());    System.out.println(t2.getThreadGroup().getName());    //通過組名稱設定後台線程,表示該組的線程都是後台線程    tg.setDaemon(true);
                    (5)線程池

                    程式啟動一個新線程成本是比較高的,因為它涉及到要與作業系統進行互動。而使用線程池可以很好的提高效能,尤其是當程式中要建立大量生存期很短的線程時,更應該考慮使用線程池。

                    • 線程池裡的每一個線程代碼結束後,並不會死亡,而是再次回到線程池中成為空白閑狀態,等待下一個對象來使用。
                    • 在JDK5之前,我們必須手動實現自己的線程池,從JDK5開始,Java內建支援線程池
                    • JDK5新增了一個Executors工廠類來產生線程池,有如下幾個方法

                      public static ExecutorService newCachedThreadPool()

                      建立一個具有緩衝功能的線程池緩衝:百度瀏覽過的資訊再次訪問   

                      public static ExecutorService newFixedThreadPool(int nThreads)

                      建立一個可重用的,具有固定線程數的線程池

                      public static ExecutorService newSingleThreadExecutor()

                      建立一個只有單線程的線程池,相當於上個方法的參數是1   

                      protected void shutdown()
                      順序關閉線程池中的線程 這些方法的返回值是ExecutorService對象,該對象表示一個線程池,可以執行Runnable對象或者Callable對象代表的線程。它提供了如下方法
                      Future submit(Runnable task)
                      Futuresubmit(Callabletask)

                      (6)多線程實現的第三種方案

                      實現Callable介面 步驟和剛才示範線程池執行Runnable對象的差不多。 但是還可以更好玩一些,求和案例示範 好處: 可以有返回值 可以拋出異常 弊端: 代碼比較複雜,所以一般不用

                      匿名內部類方式使用多線程

                      new Thread(){代碼…}.start(); New Thread(new Runnable(){代碼…}).start();

                      多線程的應用定時器的使用描述:
                      • 定時器是一個應用十分廣泛的線程工具,可用於調度多個定時任務以後台線程的方式執行。在Java中,可以通過Timer和TimerTask類來實現定義調度的功能

                      • Timer 一種工具,線程用其安排以後在後台線程中執行的任務。可安排任務執行一次,或者定期重複執行。

                        public Timer()
                        public void schedule(TimerTasktask, longdelay)
                        public void schedule(TimerTask task,long delay,long period)
                        * TimerTask 任務類用於為Timer指定任務 public abstract void run()
                        public boolean cancel()
                        * 開發中
                        Quartz是一個完全由java編寫的開源調度架構。

                        線程的生命週期轉換圖:


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.