摘要:在程序開發中一定遇到并發編程的場景雖然我們大部分時間并不直接使用但是是多線程的基礎面試中也會總是被問到與線程有關的問題那么線程都有哪些知識呢最近在研究線程的源碼的時候也總結了關于線程一些基本知識線程是什么線程是輕量級的進程是操作系統調度任務
在程序開發中, 一定遇到并發編程的場景, 雖然我們大部分時間并不直接使用Thread, 但是Thread是多線程的基礎, 面試中也會總是被問到與線程有關的問題; 那么線程都有哪些知識呢? 最近在研究線程的源碼的時候也總結了關于線程一些基本知識;線程是什么
線程是輕量級的進程, 是操作系統調度任務到CPU的最小單元;
多線程編程的優點1、多線程編程能夠最大程度的利用多核設備上面的CPU資源, 保證任務處理的足夠快, 及時響應客戶端的額請求
2、線程的創建的代價比創建進程的代價小很多, 同時多線程的上下文切換也更快; 《操作系統概念 第六版》 在Solaris 2上面, 創建進程比創建線程慢30倍, 而進程的上下文切換比線程的上下文切換慢5倍;
Java中線程的狀態有哪些查看java.lang.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: *
A thread in the waiting state is waiting for another thread to * perform a particular action. * * For example, a thread that has called Object.wait() * on an object is waiting for another thread to call * Object.notify() or Object.notifyAll() on * that object. A thread that has called Thread.join() * 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: *
1、NEW: 線程還沒有啟動的時候, 狀態就是NEW 即 新建狀態
2、RUNNABLE: 當一個線程處于運行中或者等待CPU調度的時候, 狀態就是 RUNNABLE狀態; 有些地方也稱為 就緒狀態
3、BLOCKED: 當一個線程在等待別的線程釋放鎖資源的時候, 狀態就是BLOCKED, 或者在該線程獲取到鎖之后, 在同步代碼塊里面調用了Wait方法, 這時候釋放鎖, 在獲取到其他線程的notify或者notifyAll通知之后, 重新進入 同步代碼塊這段時間 該線程也是BLOCKED狀態的;
4、WAITING: 當正在運行的線程調用了Object.wait()方法 或者 Thread.join()方法 或者 LockSupport.park()方法之后, 會進入到WAITING狀態
5、TIMED_WAITING: 當正在運行的線程調用Object.wait(n) 或者 Thread.join(n) 或者 LockSupport.parkUntil(blocker, n) 會進入到 TIMED_WAITING 狀態
6、TERMINATED: 當線程結束后, 會進入到 TERMINATED 狀態.
狀態轉換如下, 該圖中比Java的狀態多了一個RUNNING狀態, 來區別 線程的就緒狀態 與 運行狀態 更加方便讀者理解;
線程狀態轉換 線程狀態轉換之NEW下面來看一下線程的狀態轉換用Java怎么實現:
如上面所述: 剛剛創建的線程處于NEW狀態, 那么我們可以通過如下代碼打印其狀態:
Thread thread = new Thread(new Runnable() { public void run() { } }); System.out.println(thread.getState());線程狀態轉換之RUNNABLE
那么線程如何進入到RUNNABLE狀態呢? 調用Thread的start方法即可; 我們在Runnable的實現里面增加對于當前線程狀態的打印即可:
public static void main(String[] args) { Thread thread = new Thread(new Runnable() { public void run() { System.out.println("線程進入:" + Thread.currentThread().getState()); } }); System.out.println(thread.getState()); thread.start(); }線程狀態轉換之TIMED_WAITING
那么線程怎么進入到TIMED_WAITING狀態呢? 通過調用 sleep(n) join(n) 或者 wait(n)都可以進入到TIMED_WAITING狀態:
調用Thread.sleep()
public static void main(String[] args) { Thread thread = new Thread(new Runnable() { public void run() { System.out.println("線程進入:" + Thread.currentThread().getState()); try { Thread.sleep(1000 * 60); } catch (InterruptedException e) { e.printStackTrace(); } } }); System.out.println(thread.getState()); thread.start(); }
調用obj.wait(time)
public static void main(String[] args) { Thread thread = new Thread(new Runnable() { public void run() { synchronized (Client.class) { System.out.println("線程進入:" + Thread.currentThread().getState()); try { Client.class.wait(60 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }); System.out.println(thread.getState()); thread.start(); }
上圖中表示: 在Client.class上面等待; 等待其他對象調用Client.class.notify()方法或者等待時間到期.
調用thread.join(time)
public static void main(String[] args) { final Thread thread = new Thread(new Runnable() { public void run() { synchronized (Client.class) { System.out.println("線程進入:" + Thread.currentThread().getState()); try { Client.class.wait(60 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Client.class對象上等待超時"); } } }); System.out.println(thread.getState()); thread.start(); Thread thread2 = new Thread(new Runnable() { public void run() { synchronized (Client.class) { try { thread.join(50 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread1結束"); } } }); thread2.start(); }
表示 第二個線程在等待第一個線程執行完成或者超時;
線程狀態轉換之WAITING如果想要一個線程進入到WAITING狀態, 那么只需要跟上面步驟一樣, Thread.sleep()除外, 但是調用的時候不要傳超時時間即可;
public static void main(String[] args) { final Thread thread = new Thread(new Runnable() { public void run() { synchronized (Client.class) { System.out.println("線程進入:" + Thread.currentThread().getState()); try { Client.class.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("被其他線程調用Client.class.notify()喚醒"); } } }); System.out.println(thread.getState()); thread.start(); Thread thread2 = new Thread(new Runnable() { public void run() { synchronized (Client.class) { try { thread.join(50 * 1000); Client.class.notify(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread1結束"); } } }); thread2.start(); }
只要是沒有時間的等待都會處于WAITING狀態, 比如把上面代碼修改一下, 換成join()也可以讓線程處于 WAITING狀態:
public static void main(String[] args) { final Thread thread = new Thread(new Runnable() { public void run() { synchronized (Client.class) { System.out.println("線程進入:" + Thread.currentThread().getState()); try { Client.class.wait(50 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("被其他線程調用Client.class.notify()喚醒"); } } }); System.out.println(thread.getState()); thread.start(); Thread thread2 = new Thread(new Runnable() { public void run() { synchronized (Client.class) { try { System.out.println("即將進入等待線程1完成的狀態"); thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread1結束"); } } }); thread2.start(); }
如上代碼表示線程2會在線程1執行結束之后再結束, 所以線程2就會進入到WATIING狀態
線程狀態轉換之BLOCKED上面已經看到, 通過調用線程的函數就可以控制線程的狀態, 那么如何進入到BLOCKED狀態呢?進入到BLOCKED狀態, 按照上面的轉換圖 可以翻譯為 多個線程出現竟態的時候, 其他線程會進入BLOCKED狀態, 只有一個線程會在RUNNABLE狀態,比如如下代碼:
public static void main(String[] args) { final Thread thread = new Thread(new Runnable() { public void run() { synchronized (Client.class) { System.out.println("線程進入:" + Thread.currentThread().getState()); try { Thread.sleep(1000 * 50); } catch (InterruptedException e) { e.printStackTrace(); } } } }); System.out.println(thread.getState()); thread.start(); Thread thread2 = new Thread(new Runnable() { public void run() { synchronized (Client.class) { try { System.out.println("即將進入等待線程1完成的狀態"); thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread1結束"); } } }); thread2.start(); }
當然, 對于A線程調用了Object.class.wait()方法釋放鎖之后, 最后被其他線程調用Object.class.notify() A線程再次進入RUNNABLE之前的狀態就是 BLOCKED;
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/73607.html
摘要:開發中不可避免用到多線程情況,比如中常見的都是運用到多線程,多線程的根本目的是為了更快的執行。其他常用到的多線程比如設計到大量操作用多線程可明顯提升效率。中最基礎的并發類就是是一個接口,只要實現實現,重寫方法就可以實現多線程操作。 java開發中不可避免用到多線程情況,比如web中常見的Servlet、Struts2都是運用到多線程,多線程的根本目的是為了更快的執行。其他常用到的多線程...
摘要:可以用代替可以用代替定義的對象的值是不可變的今天就先到這里,大家可以看看這些內容的拓展記得點關注看更新,謝謝閱讀 前言 java高并發第二篇講的是java線程的基礎依舊不多說廢話 線程和進程 進程是操作系統運行的基礎,是一個程序運行的實體,windows上打開任務管理器就能看到進程線程是輕量級的進程,是程序執行的最小單位,是在進程這個容器下進行的 線程基本操作 新建一個線程類有兩種方式...
摘要:基本在項目開發中基本不會用到但是面試官是比較喜歡問這類問題的所以還是有必要了解一下該類的功能與原理的是什么是一個將在多線程中為每一個線程創建單獨的變量副本的類當使用來維護變量時會為每個線程創建單獨的變量副本避免因多線程操作共享變量而導致的數 ThreadLocal基本在項目開發中基本不會用到, 但是面試官是比較喜歡問這類問題的;所以還是有必要了解一下該類的功能與原理的. Thread...
摘要:線程間通信其實就是多個線程操作同一個資源,但動作不同。同步前提是多線程。將該線程載入線程池,等待喚醒。該方法拋出異常,故需要配合使用隨機喚醒線程池中一線程。線程為了檢測死鎖,它需要遞進地檢測所有被請求的鎖。 線程間通信 其實就是多個線程操作同一個資源,但動作不同。示例:在某個數據庫中,Input輸入人的姓名,性別,Output輸出,兩個線程同時作用。思考:1.明確哪些代碼是多線程操作的...
摘要:常用于臨時加入線程。重載形式等待被的線程執行完成。當正在運行的線程都是守護線程時,虛擬機退出。為線程對象設置優先級類定義了三個靜態常量停止線程釋放執行線程的執行權,讓重新調度一次,但仍有可能回到該線程。 join()線程當A線程執行到了B線程的join()方法時,A線程就會等待B線程執行完,A線程才會執行。join()常用于臨時加入線程。重載形式:join():等待被join的線程執行...
閱讀 2102·2021-11-19 09:58
閱讀 1701·2021-11-15 11:36
閱讀 2867·2019-08-30 15:54
閱讀 3386·2019-08-29 15:07
閱讀 2759·2019-08-26 11:47
閱讀 2805·2019-08-26 10:11
閱讀 2496·2019-08-23 18:22
閱讀 2744·2019-08-23 17:58