JAVA多線程的初級認識1--線程的基本認識

  • 爲什麼要有多線程?

從最開始的真空管穿孔打卡,到後來的晶體管批處理系統,再到後來的集成電路多核並行執行。從硬件資源的級別程度逐漸提高,但是軟件如果對硬件資源利用率低,也是一種資源的損耗,所以隨之而來的進程和線程應運而生。

爲什麼有了進程還需要出現線程?

先說一下進程的弊端。

  • 相比進程,對於CPU時間片切換,線程是輕量級的。
  • 僅有單線程無線程的話,如果單個IO阻塞了整個進程,那麼程序就會Hang住,從而降低了資源利用率。

而線程是現在cpu執行的最小單位,衆所周知,CPU是通過時間片切換來進行類似於併發的效果的。線程的上下文切換的量級遠小於線程,從而可以更大程度的利用CPU資源。

  • JAVA的線程狀態

其實學習線程狀態最好是看看Thread類源碼,裏面有一個State的Enum類,寫幾個demo看看~現在截圖一下看看Thread源碼關於線程狀態的註釋:

public enum State {
    /**
     * Thread state for a thread which has not yet started.
     */
    NEW,

    /**
     * Thread state for a runnable thread.  A thread in the runnable
     * state is executing in the Java virtual machine but it may
     * be waiting for other resources from the operating system
     * such as processor.
     */
    RUNNABLE,

    /**
     * Thread state for a thread blocked waiting for a monitor lock.
     * A thread in the blocked state is waiting for a monitor lock
     * to enter a synchronized block/method or
     * reenter a synchronized block/method after calling
     * {@link Object#wait() Object.wait}.
     */
    BLOCKED,

    /**
     * Thread state for a waiting thread.
     * A thread is in the waiting state due to calling one of the
     * following methods:
     * <ul>
     *   <li>{@link Object#wait() Object.wait} with no timeout</li>
     *   <li>{@link #join() Thread.join} with no timeout</li>
     *   <li>{@link LockSupport#park() LockSupport.park}</li>
     * </ul>
     *
     * <p>A thread in the waiting state is waiting for another thread to
     * perform a particular action.
     *
     * For example, a thread that has called <tt>Object.wait()</tt>
     * on an object is waiting for another thread to call
     * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
     * that object. A thread that has called <tt>Thread.join()</tt>
     * is waiting for a specified thread to terminate.
     */
    WAITING,

    /**
     * Thread state for a waiting thread with a specified waiting time.
     * A thread is in the timed waiting state due to calling one of
     * the following methods with a specified positive waiting time:
     * <ul>
     *   <li>{@link #sleep Thread.sleep}</li>
     *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
     *   <li>{@link #join(long) Thread.join} with timeout</li>
     *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
     *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
     * </ul>
     */
    TIMED_WAITING,

    /**
     * Thread state for a terminated thread.
     * The thread has completed execution.
     */
    TERMINATED;
}

一共6種狀態,具體的轉換圖如下:

查看線程狀態可以使用JDK提供的工具來進行輔助~包括JPS,JSTACK。

JPS獲取java進程號。

JSTACK可以獲取線程堆棧的具體信息

 

  • 線程的啓動和銷燬

線程的啓動,不考慮Callable和Future的前提下,只考慮Thread和Runnable。我們看Thread的源碼,我們都是通過調用Start方法而非run方法來啓動線程的。

start方法查看進去,會調用一個start0的native方法。該方法我們就看不到了,因爲是cpp源碼,我們可以找到http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/00cd9dc3c2b5/src/share/native/java/lang/Thread.c 來看具體的Thread的源碼~然後一步一步對應,通過start0-->jvm.cpp裏面的JVM_Start_Thread-->thread.cpp裏面的Thread.Java_thread和Start(需要下載hotspot源碼)-->Thread.start裏面會調用run方法

 

線程的銷燬

Thread提供了stop和suspend方法,但是都已經過時,其實想想也很正確,A線程調用B線程的stop方法,本身就是一個很奇怪的事情。Thread提供了一個interrupt函數來優雅的中斷一個線程。看源碼又會走到c++源碼中,具體細節不多講了,結果能就是有一個volatile的interrupted的變量變成true,然後呢告知線程,有人向中斷你,僅此而已,至於會不會被中斷,是線程自己的事情。簡單來說就是:

A想中斷B線程,就調用B線程interrupt方法,然後B線程的interrupted boolean變量設置爲true,B線程收到中斷信號,如果不想處理,直接不理這個信號就好,然後調用Thread.interrupted方法來對interrupted變量進行復位。

Thread提供一種IsInterrupted方法來判斷線程是否被中斷。

 

 

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