多線程三分鐘就能夠入個門了!

前言

以前花了一個星期回顧了Java集合:java

在寫文章以前通讀了一遍《Java 核心技術 卷一》的併發章節和《Java併發編程實戰》前面的部分,回顧了一下之前寫過的筆記。從今天開始進入多線程的知識點咯~面試

以前在學習Java基礎的時候學多線程基礎仍是挺認真的,但是在後面一直沒有回顧它,長此以往就把它給忘掉得差很少了..在學習JavaWeb上也一直沒用到多線程的地方(我作的東西太水了...)。編程

因爲面試這一部分是佔很大比重的,而且學習多線程對我之後的提高也是頗有幫助的(自覺得)。windows

我其實也是至關於從零開始學多線程的,若是文章有錯的地方還請你們多多包含,不吝在評論區下指正呢~~安全

1、初識多線程

1.1介紹進程

講到線程,又不得不提進程了~微信

進程咱們估計是很瞭解的了,在windows下打開任務管理器,能夠發現咱們在操做系統上運行的程序都是進程:多線程

 

 

進程的定義:併發

進程是程序的一次執行,進程是一個程序及其數據在處理機上順序執行時所發生的活動,進程是具備獨立功能的程序在一個數據集合上運行的過程,它是系統進行資源分配和調度的一個獨立單位jvm

  • 進程是系統進行資源分配和調度的獨立單位。每個進程都有它本身的內存空間和系統資源

1.2回到線程

那系統有了進程這麼一個概念了,進程已是能夠進行資源分配和調度了,爲何還要線程呢ide

爲使程序能併發執行,系統必須進行如下的一系列操做:

  • (1)建立進程,系統在建立一個進程時,必須爲它分配其所必需的、除處理機之外的全部資源,如內存空間、I/O設備,以及創建相應的PCB;
  • (2)撤消進程,系統在撤消進程時,又必須先對其所佔有的資源執行回收操做,而後再撤消PCB;
  • (3)進程切換,對進程進行上下文切換時,須要保留當前進程的CPU環境,設置新選中進程的CPU環境,於是須花費很多的處理機時間。

 

 

能夠看到進程實現多處理機環境下的進程調度,分派,切換時,都須要花費較大的時間和空間開銷

引入線程主要是**爲了提升系統的執行效率,減小處理機的空轉時間和調度切換的時間,以及便於系統管理。**使OS具備更好的併發性

  • 簡單來講:進程實現多處理很是耗費CPU的資源,而咱們引入線程是做爲調度和分派的基本單位(取代進程的部分基本功能**【調度】**)。

那麼線程在哪呢??舉個例子:

 

 

也就是說:在同一個進程內又能夠執行多個任務,而這每個任務我就能夠看出是一個線程

  • 因此說:一個進程會有1個或多個線程的

1.3進程與線程

因而咱們能夠總結出:

  • 進程做爲資源分配的基本單位
  • 線程做爲資源調度的基本單位,是程序的執行單元,執行路徑(單線程:一條執行路徑,多線程:多條執行路徑)。是程序使用CPU的最基本單位。

線程有3個基本狀態

  • 執行、就緒、阻塞

線程有5種基本操做

  • 派生、阻塞、激活、 調度、 結束

 

 

線程的屬性:

  • 1)輕型實體;
  • 2)獨立調度和分派的基本單位;
  • 3)可併發執行;
  • 4)共享進程資源。

線程有兩個基本類型

    1. 用戶級線程:管理過程所有由用戶程序完成,操做系統內核心只對進程進行管理。
    1. 系統級線程(核心級線程):由操做系統內核進行管理。操做系統內核給應用程序提供相應的系統調用和應用程序接口API,以使用戶程序能夠建立、執行以及撤消線程。

 

 

值得注意的是:多線程的存在,不是提升程序的執行速度。其實是爲了提升應用程序的使用率,程序的執行其實都是在搶CPU的資源,CPU的執行權。多個進程是在搶這個資源,而其中的某一個進程若是執行路徑比較多,就會有更高的概率搶到CPU的執行權

1.4並行與併發

並行:

  • 並行性是指同一時刻內發生兩個或多個事件。
  • 並行是在不一樣實體上的多個事件

併發:

  • 併發性是指同一時間間隔內發生兩個或多個事件。
  • 併發是在同一實體上的多個事件

因而可知:並行是針對進程的,併發是針對線程的

1.5Java實現多線程

上面說了一大堆基礎,理解完的話。咱們回到Java中,看看Java是如何實現多線程的~

Java實現多線程是使用Thread這個類的,咱們來看看Thread類的頂部註釋

 

 

經過上面的頂部註釋咱們就能夠發現,建立多線程有兩種方法:

  • 繼承Thread,重寫run方法
  • 實現Runnable接口,重寫run方法

1.5.1繼承Thread,重寫run方法

建立一個類,繼承Thread,重寫run方法

public class MyThread extends Thread {

	@Override
	public void run() {
		for (int x = 0; x < 200; x++) {
			System.out.println(x);
		}
	}

}

咱們調用一下測試看看:

public class MyThreadDemo {
	public static void main(String[] args) {
		// 建立兩個線程對象
		MyThread my1 = new MyThread();
		MyThread my2 = new MyThread();

		my1.start();
		my2.start();
	}
}

 

 

1.5.2實現Runnable接口,重寫run方法

實現Runnable接口,重寫run方法

public class MyRunnable implements Runnable {

	@Override
	public void run() {
		for (int x = 0; x < 100; x++) {
			System.out.println(x);
		}
	}

}

咱們調用一下測試看看:

public class MyRunnableDemo {
	public static void main(String[] args) {
		// 建立MyRunnable類的對象
		MyRunnable my = new MyRunnable();

		Thread t1 = new Thread(my);
		Thread t2 = new Thread(my);

		t1.start();
		t2.start();
	}
}

結果仍是跟上面是同樣的,這裏我就不貼圖了~~~

1.6Java實現多線程須要注意的細節

不要將run()start()搞混了~

run()和start()方法區別:

  • run():僅僅是封裝被線程執行的代碼,直接調用是普通方法
  • start():首先啓動了線程,而後再由jvm去調用該線程的run()方法。

jvm虛擬機的啓動是單線程的仍是多線程的?

  • 是多線程的。不只僅是啓動main線程,還至少會啓動垃圾回收線程的,否則誰幫你回收不用的內存~

那麼,既然有兩種方式實現多線程,咱們使用哪種???

通常咱們使用實現Runnable接口

  • 能夠避免java中的單繼承的限制
  • 應該將併發運行任務和運行機制解耦,所以咱們選擇實現Runnable接口這種方式!

2、總結

這篇主要是講解了線程是什麼,理解線程的基礎對咱們日後的學習是有幫助的。這裏主要是簡單的入了個門

在閱讀頂部註釋的時候咱們發現有」優先級「、」後臺線程「這類的詞,這篇是沒有講解他們是什麼東西的~因此下一篇主要講解的是Thread的API~敬請期待哦~

使用線程其實會致使咱們數據不安全,甚至程序沒法運行的狀況的,這些問題都會再後面講解到的~

以前在學習操做系統的時候根據《計算機操做系統-湯小丹》這本書也作了一點點筆記,都是比較淺顯的知識點。或許對你們有幫助~

參考資料:

  • 《Java 核心技術卷一》
  • 《Java併發編程實戰》
  • 《計算機操做系統-湯小丹》

若是文章有錯的地方歡迎指正,你們互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同窗,能夠關注微信公衆號:Java3y

文章的目錄導航

相關文章
相關標籤/搜索