作者主頁:paper jie_博客
本文作者:大家好,我是paper jie,感謝你閱讀本文,歡迎一建三連哦。
本文錄入于《vaEE》專欄,本專欄是針對于大學生,編程小白精心打造的。筆者用重金(時間和精力)打造,將MySQL基礎知識一網打盡,希望可以幫到讀者們哦。
其他專欄:《MySQL》《C語言》《javaSE》《數據結構》等
內容分享:本期將會分享多線程知識~
前言
在上篇文章中,我們提到了多進程這個概念,通過多進程我們就可以同時多次運行多個程序了.但是,這這里其實還是有一個比較明顯的缺點.就是進程在創建的時候需要申請資源,銷毀的時候需要釋放資源.這就會導致開銷比較大.再這個前提下,就延伸出了多線程這個概念.
多線程
什么是多線程
多線程也可以叫輕量級進程.一個進程是可以包含多個線程的,且至少得有一個線程.線程也可以單獨執行,每個線程都有一個自己的PCB,有一些支持調度的重要屬性,比如狀態,優先級,記賬信息,上下文等. 多線程主要就是為了解決進程申請資源和釋放資源開銷大的這個問題.且它也可以提高一個進程的效率.多線程是Java常用的編程方式.
為什么多線程可以解決多進程開銷大的問題
這是因為一個進程中的所有線程他們的資源是共享的.隨著進程創建好,第一個線程也隨著創建好了,第一個線程創建的時候會申請好資源,再后面隨著創建好的線程都會共用這份資源.這樣就意味著,除了第一個線程需要申請和釋放資源外,其他的線程都不用在申請資源了.但這不是隨便兩個線程就可以共享.這需要一組相關的線程才可以,這就叫做線程組.
如果在深究下去的話,為什么它們能資源共享?這是因為線程中會有內存指針這樣的屬性,它們的內存指正指向的都是同一塊內存,這塊內存就是第一個線程申請過來的.硬盤資源也是如此,它們也會有一個文件操作符表,是用來操作硬盤資源的.它們表示的也是同一份硬盤資源.?
這里就可以得出一個概念: 在多線程中,進程是分配資源的基本單位. 線程是調度執行的基本單位.
多線程的缺點?
多線程也不是十全十美的,它也有一些缺點.線程不是越多越好,太多了會導致調度開銷比較大. 且進程與進程之間是相互獨立的,但是多線程中,一個線程掛了,這個進程中的其他線程有可能也會隨著異常中斷.
進程與線程的區別?
1. 一個進程包含多個線程,且最少有一個線程.
2. 進程是資源分配的基本單位,線程是調度執行的基本單位.
3. 進程間的資源是獨立的,但一個進程內的線程是共享資源的.
4.線程也是一單獨的執行流,它也有PCB,里面也有狀態,優先級,記賬信息,上下文
5. 進程與進程間是相互獨立,互不干擾的.但是一個進程中,一個線程掛了,其他線程也可能異常中斷.
6. 線程不是越多越好,需要適量.不然調度開銷會比較大.
7. 線程與線程間可能會相互干擾,會有線程安全問題.
Java中的多線程
線程是操作系統的概念.操作系統內核中實現了線程這樣的概念.且對用戶提供了統一的API供用戶使用.但是這些API大多是拿C/C++寫的.在這個前提下,Java標準庫中對操作系統的API進行了進一步的抽象與封裝. 在Java中表示線程就是用Thread這個類.
第一個多線程程序
Thread就是Java提供的API.在創建一個類后需要繼承Thread,再重寫他的run方法.run方法是這個線程的入口. 還需要創建實例,這才是一個線程.最后需要使用start方法,它是真正的在內核中創建了線程.
class MyThread extends Thread {@Override//run方法就是這個線程的入口方法public void run() {System.out.println("進去執行啦");}
}public class ThreadDemo {public static void main(String[] args) {//創建實例 線程實例才是真正的線程MyThread myThread = new MyThread();//開始執行 調用Thread的start才是真正的調用系統 api,在系統內核中創建線程myThread.start();}
}
什么是內核
內核就是用來管理管理硬件資源,為軟件提供穩定的運行環境.操作系統可以簡單的認為是 內核 + 配套的應用程序. 操作系統里面分為內核態和用戶態.一般我們的應用程序都是運行在用戶態中.但再需要使用硬件資源時,不能直接對硬件資源操作,就需要通過操作系統提供的API進一步在內核中操作.
為什么要劃分出內核態和用戶態
目的就是為了穩定.為了防止程序把硬件資源,軟件資源搞壞了.系統提供的API是合法的.應用程序只能調用這些API,就不會對操作系統或資源造成極大的傷害. 因為在一些極端的情況下程序直接操作硬件可以會將硬件燒壞.
我們可以將操作系統想象成銀行,辦事窗口是內核區,大廳是用戶區.大廳的滑稽需要存錢或者取錢需要通過窗口的工作人員來處理,不能自己直接進去拿.
多線程與普通程序的區別
多線程和普通程序的區別就是每個線程都是一個獨立的執行流,他們都是并發執行的,并不是順序執行代碼.
栗子:
class MyThread extends Thread {@Overridepublic void run() {while(true) {System.out.println("hello Thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
public class ThreadDemo1 {public static void main(String[] args) {Thread t = new MyThread();t.start();while(true) {System.out.println("hello main");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
通過代碼執行打印效果,我們可以發現并不是先打印hello THread在打印 hello main,而是同時執行打印,且是隨機的.因為內核中有一個調度器模塊.實現方式就是隨機調度的效果.
使用jconsole命令觀察線程
在本地上找到jbk的bin,再找到jconsole這個可執行文件,雙擊打不來可以用管理員運行方式打開.
我們可以在線程這一欄中觀察我們創建的線程.?