首頁(yè)技術(shù)文章正文

java高級(jí)特性-更新版本

更新時(shí)間:2018-09-14 來源:黑馬程序員 瀏覽量:

  1.  java多線程增強(qiáng)

  2.  java多線程基本知識(shí)

  3. 進(jìn)程介紹

        不管是我們開發(fā)的應(yīng)用程序,還是我們運(yùn)行的其他的應(yīng)用程序,都需要先把程序安裝在本地的硬盤上。然后找到這個(gè)程序的啟動(dòng)文件,啟動(dòng)程序的時(shí)候,其實(shí)是電腦把當(dāng)前的這個(gè)程序加載到內(nèi)存中,在內(nèi)存中需要給當(dāng)前的程序分配一段獨(dú)立的運(yùn)行空間。這片空間就專門負(fù)責(zé)當(dāng)前這個(gè)程序的運(yùn)行。

        不同的應(yīng)用程序運(yùn)行的過程中都需要在內(nèi)存中分配自己獨(dú)立的運(yùn)行空間,彼此之間不會(huì)相互的影響。我們把每個(gè)獨(dú)立應(yīng)用程序在內(nèi)存的獨(dú)立空間稱為當(dāng)前應(yīng)用程序運(yùn)行的一個(gè)進(jìn)程。

進(jìn)程:它是內(nèi)存中的一段獨(dú)立的空間,可以負(fù)責(zé)當(dāng)前應(yīng)用程序的運(yùn)行。當(dāng)前這個(gè)進(jìn)程負(fù)責(zé)調(diào)度當(dāng)前程序中的所有運(yùn)行細(xì)節(jié)。

1.1.2. 線程介紹

        啟動(dòng)的QQ聊天軟件,需要和多個(gè)人進(jìn)行聊天。這時(shí)多個(gè)人之間是不能相互影響,但是它們都位于當(dāng)前QQ這個(gè)軟件運(yùn)行時(shí)所分配的內(nèi)容的獨(dú)立空間中。

        在一個(gè)進(jìn)程中,每個(gè)獨(dú)立的功能都需要獨(dú)立的去運(yùn)行,這時(shí)又需要把當(dāng)前這個(gè)進(jìn)程劃分成多個(gè)運(yùn)行區(qū)域,每個(gè)獨(dú)立的小區(qū)域(小單元)稱為一個(gè)線程。

線程:它是位于進(jìn)程中,負(fù)責(zé)當(dāng)前進(jìn)程中的某個(gè)具備獨(dú)立運(yùn)行資格的空間。

進(jìn)程是負(fù)責(zé)整個(gè)程序的運(yùn)行,而線程是程序中具體的某個(gè)獨(dú)立功能的運(yùn)行。一個(gè)進(jìn)程中至少應(yīng)該有一個(gè)線程。

1.1.3. 多線程介紹

        現(xiàn)在的操作系統(tǒng)基本都是多用戶,多任務(wù)的操作系統(tǒng)。每個(gè)任務(wù)就是一個(gè)進(jìn)程。而在這個(gè)進(jìn)程中就會(huì)有線程。

        真正可以完成程序運(yùn)行和功能的實(shí)現(xiàn)靠的是進(jìn)程中的線程。

多線程:在一個(gè)進(jìn)程中,我們同時(shí)開啟多個(gè)線程,讓多個(gè)線程同時(shí)去完成某些任務(wù)(功能)。

多線程的目的:提高程序的運(yùn)行效率。

1.1.4. 多線程運(yùn)行的原理

        在電腦中負(fù)責(zé)程序運(yùn)行的控制器CPU。

        其實(shí)真正電腦中的程序的運(yùn)行不是同時(shí)在運(yùn)行的。CPU負(fù)責(zé)程序的運(yùn)行,而CPU在運(yùn)行程序的過程中某個(gè)時(shí)刻點(diǎn)上,它其實(shí)只能運(yùn)行一個(gè)程序。而不是多個(gè)程序。而CPU它可以在多個(gè)程序之間進(jìn)行高速的切換。而切換頻率和速度太快,導(dǎo)致人的肉看看不到。

每個(gè)程序就是進(jìn)程, 而每個(gè)進(jìn)程中會(huì)有多個(gè)線程,而CPU是在這些線程之間進(jìn)行切換。

了解了CPU對(duì)一個(gè)任務(wù)的執(zhí)行過程,我們就必須知道,多線程可以提高程序的運(yùn)行效率,但不能無限制的開線程。

1.1.5. Java關(guān)于線程的描述

程序運(yùn)行靠的線程,在每個(gè)程序中都會(huì)一個(gè)線程的存在,線程是程序運(yùn)行過程中存在一類事物,Java就必須對(duì)這個(gè)事物有類的描述和封裝。

在Java中使用Thread類描述線程這個(gè)事物。

1.1.6. 實(shí)現(xiàn)線程的兩種方式

1、繼承Thread的原理

        為什么要繼承Thread類?

線程是程序運(yùn)行過程中的最基本的單元。而Java對(duì)線程使用的Thread這個(gè)類進(jìn)行描述。而我們現(xiàn)在希望通過自己的代碼操作線程,自己的代碼應(yīng)該需要和Thread類之間產(chǎn)生關(guān)系。這里我們采用的繼承的關(guān)系。

當(dāng)我們繼承了Thread類之后,我們自己的類也就變成了線程類。我們自己的類就繼承到了Thread類中的所有功能,并且自己的類就可以對(duì)線程進(jìn)行各種操作(開啟線程,停止線程等)。

為什么要復(fù)寫run方法

為什么要使用線程:因?yàn)槲覀兿M绦蛑械哪扯未a可以同時(shí)運(yùn)行,提高程序的運(yùn)行效率。

我們定義的類繼承了Thread的之后,其實(shí)在Thread類中有個(gè)run方法,它是開啟線程之后,就會(huì)直接去運(yùn)行的方法。而Java在設(shè)計(jì)線程類(Thread)的時(shí)候,就已經(jīng)明確了線程應(yīng)該執(zhí)行的某段代碼需要書寫在run方法中,之后在run方法中的代碼開啟線程之后才能正常的運(yùn)行。

我們使用線程的目的是讓線程執(zhí)行后來自己程序中的某些代碼, 而Java中規(guī)定需要線程執(zhí)行的代碼必須寫run方法中,Thread類中的run方法中并沒有我們真正需要多線程運(yùn)行的代碼,而開啟線程又要去運(yùn)行run方法,這時(shí)我們只能沿用Thread類run方法的定義格式,然后復(fù)寫run方法的方法體代碼。

復(fù)寫run方法的目的是明確線程要執(zhí)行的代碼,只有把代碼寫在run方法中,線程開啟后才會(huì)去執(zhí)行。

需要線程執(zhí)行的代碼:這段代碼稱為線程要執(zhí)行的任務(wù)。線程要執(zhí)行的任務(wù),需要書寫在run方法中。

為什么不直接調(diào)用run方法,而調(diào)用start方法

當(dāng)書寫了一個(gè)類繼承了Thread類之后,這個(gè)子類也變成線程類。這時(shí)可以創(chuàng)建這個(gè)子類的對(duì)象,一旦創(chuàng)建Thread的子類對(duì)象,就相當(dāng)于擁有了當(dāng)前的線程對(duì)象。

創(chuàng)建Thread的子類對(duì)象,只是在內(nèi)存中有了線程這個(gè)對(duì)象,但是線程還不能真正的去運(yùn)行。

要讓線程真正的在內(nèi)存運(yùn)行起來,必須調(diào)用start方法,這樣才能夠在內(nèi)存開啟一片新的內(nèi)存空間,然后負(fù)責(zé)當(dāng)前線程需要執(zhí)行的任務(wù)。

我們直接通過線程對(duì)象去調(diào)用run方法,這時(shí)只是對(duì)象調(diào)用普通的方法,并沒有在內(nèi)存中開啟新的內(nèi)存空間運(yùn)行任務(wù)代碼。只有調(diào)用start方法才會(huì)開啟新的空間。并在新的空間中自動(dòng)去運(yùn)行run方法。

2、開啟線程的第二種方式

創(chuàng)建線程的另一種方法是聲明實(shí)現(xiàn) Runnable 接口的類。該類然后實(shí)現(xiàn) run 方法。然后可以分配該類的實(shí)例,在創(chuàng)建 Thread 時(shí)作為一個(gè)參數(shù)來傳遞并啟動(dòng)。

實(shí)現(xiàn)Runnable接口的原理

1、java單繼承的原因:

        在Java中一個(gè)類只能有一個(gè)直接父類,如果一個(gè)類已經(jīng)繼承其他的父類,那么當(dāng)前這個(gè)類中假如有需要多線程操作的代碼,這時(shí)這類是無法再繼承Thread類的。這樣就會(huì)導(dǎo)致當(dāng)前這個(gè)類中的某些需要多線程執(zhí)行的任務(wù)代碼就無法被線程去執(zhí)行。

       

2、Java設(shè)計(jì)方面的原因:

        Thread類是專門負(fù)責(zé)描述線程本身的。Thread類可以對(duì)線程進(jìn)行各種各樣的操作。Java在設(shè)計(jì)的時(shí)候把線程要執(zhí)行的任務(wù)交給了Thread。這樣導(dǎo)致操作線程本身的功能和線程要執(zhí)行的任務(wù)功能嚴(yán)重的耦合在一起。

        線程的任務(wù)是需要后來的程序制定和分配的,而線程的操作是需要提前設(shè)計(jì)好的。Java就把線程的任務(wù)從Thread類中抽取出來,保存在Runnable接口中。

        把任務(wù)抽取到Runnable接口中之后,在這個(gè)接口中定義線程需要執(zhí)行的任務(wù)的規(guī)則,當(dāng)需要明確線程的任務(wù)時(shí),我們就讓這個(gè)類實(shí)現(xiàn)Runnable接口,只要實(shí)現(xiàn)Runnable接口的類,就相當(dāng)于明確了線程需要執(zhí)行的任務(wù)。

       

        當(dāng)一個(gè)類實(shí)現(xiàn)Runnable接口,就相當(dāng)于有了線程的任務(wù),可以是還沒有線程本身這個(gè)對(duì)象。這是我們就可以直接使用Thread這個(gè)類創(chuàng)建出線程,然后把任務(wù)交給線程。這樣就達(dá)到任務(wù)和線程的分離以及結(jié)合。

軟件設(shè)計(jì)的時(shí)候遵守原則:低耦合、高內(nèi)聚。事物和事物之間的依賴程度稱為它們的耦合度。

   

作者:黑馬程序員javaEE培訓(xùn)學(xué)院
首發(fā):http://java.itheima.com/

分享到:
在線咨詢 我要報(bào)名
和我們?cè)诰€交談!