JAVA面試題總覽--JAVA基礎(chǔ)

1. ?? ?JAVA中的幾種基本數(shù)據(jù)類型是什么,各自占用多少字節(jié)。?

類型占位取值范圍字節(jié)大小


==================================================================

2. ?? ?String類能被繼承嗎,為什么。?

public final class Stringimplements java.io.Serializable, Comparable, CharSequence

String 被final修飾了,所有不能被繼承。

1.final修飾的對(duì)象不能被修改;

2.final修飾的類不能被繼承;

3.final修飾的方法不能被重寫;

==================================================================

3. ?? ?String,Stringbuffer,StringBuilder的區(qū)別。

1.是否多線程安全

String對(duì)象因?yàn)槭遣豢勺兊模允蔷€程安全的;

StringBuffer對(duì)方法加了同步鎖或者對(duì)調(diào)用的方法加了同步鎖,所以是線程安全的;

StringBuilder非線程安全的。

2.可變與不可變

String類中使用字符數(shù)組保存字符串,如下就是,因?yàn)橛小癴inal”修飾符,所以可以知道string對(duì)象是不可變的。

?????????????? private final char value[];

StringBuffer和StringBuilder類中使用字符數(shù)組保存字符串,沒有使用final修飾,所以是可變的。

所以String對(duì)象進(jìn)行改變時(shí),是重新生成一個(gè)對(duì)象,并把引用指向新生成的對(duì)象,每次生成對(duì)象的時(shí)候都會(huì)浪費(fèi)性能,而且會(huì)產(chǎn)生很多的垃圾的中間對(duì)象,導(dǎo)致GC更加頻繁,StringBuffer和StringBuilder對(duì)象都是對(duì)對(duì)象本身進(jìn)行操作,不會(huì)改變對(duì)象的引用。所以普遍認(rèn)為當(dāng)字符串需要經(jīng)常進(jìn)行修改的情況下,String的性能比StringBuffer和StringBuilder低,但是也是有特例的:

public class Test{

public static void main(String[] args){

String string ="A"+"B"+"C";

StringBuffer stringBuffer = new StringBuffer("A").append("B").append("C");

StringBuilder stringBuilder = new StringBuilder("A").append("B").append("C");

}

}


1.這里面創(chuàng)建一個(gè)String 對(duì)象,JVM在編譯期進(jìn)行了常量折疊,直接拼接了ABC,所以在運(yùn)行的時(shí)候只進(jìn)行了兩步:從字符串常量池中獲取ABC、將string指向ABC

2.這里面創(chuàng)建一個(gè)StringBuffer和StringBuilder對(duì)象時(shí),都經(jīng)歷了七步:

a.從字符串常量池里面取出A,

b.調(diào)用StringBuilder和StringBuilder的append方法,添加A;

c.從字符串常量池里面取出B,

d.調(diào)用StringBuilder和StringBuilder的append方法,添加B;

e.從字符串常量池里面取出C,

f.調(diào)用StringBuilder和StringBuilder的append方法,添加C;

g.將?StringBuilder和StringBuilder指向?ABC

==================================================================

4. ?? ?ArrayList和LinkedList有什么區(qū)別。?

1.對(duì)ArrayList和LinkedList而言,在列表末尾增加一個(gè)元素所花的開銷都是固定的。對(duì)ArrayList而言,主要是在內(nèi)部數(shù)組中增加一項(xiàng),指向所添加的元素,偶爾可能會(huì)導(dǎo)致對(duì)數(shù)組重新進(jìn)行分配;而對(duì)LinkedList而言,這個(gè)開銷是統(tǒng)一的,分配一個(gè)內(nèi)部Entry對(duì)象。

2.在ArrayList的中間插入或刪除一個(gè)元素意味著這個(gè)列表中剩余的元素都會(huì)被移動(dòng);而在LinkedList的中間插入或刪除一個(gè)元素的開銷是固定的。

3.LinkedList不支持高效的隨機(jī)元素訪問。

4.ArrayList的空間浪費(fèi)主要體現(xiàn)在在list列表的結(jié)尾預(yù)留一定的容量空間,而LinkedList的空間花費(fèi)則體現(xiàn)在它的每一個(gè)元素都需要消耗相當(dāng)?shù)目臻g

可以這樣說:當(dāng)操作是在一列數(shù)據(jù)的后面添加數(shù)據(jù)而不是在前面或中間,并且需要隨機(jī)地訪問其中的元素時(shí),使用ArrayList會(huì)提供比較好的性能;當(dāng)你的操作是在一列數(shù)據(jù)的前面或中間添加或刪除數(shù)據(jù),并且按照順序訪問其中的元素時(shí),就應(yīng)該使用LinkedList了。

==================================================================

5.?? ?講講類的實(shí)例化順序,比如父類靜態(tài)數(shù)據(jù),父類構(gòu)造函數(shù),父類字段,子類靜態(tài)數(shù)據(jù),子類構(gòu)造函數(shù),子類字段,當(dāng)new的時(shí)候,他們的執(zhí)行順序。

類的實(shí)例化順序:先靜態(tài)再父子

父類靜態(tài)數(shù)據(jù)->子類靜態(tài)數(shù)據(jù)->父類字段->子類字段->父類構(gòu)造函數(shù)->子類構(gòu)造函數(shù)

==================================================================

6.?? ?用過哪些Map類,都有什么區(qū)別,HashMap是線程安全的嗎,并發(fā)下使用的Map是什么,他們內(nèi)部原理分別是什么,比如存儲(chǔ)方式,hashcode,擴(kuò)容,默認(rèn)容量等。

最常用的Map實(shí)現(xiàn)類有:HashMap,ConcurrentHashMap(jdk1.8),LinkedHashMap,TreeMap,HashTable;

其中最頻繁的是HashMap和ConcurrentHashMap,他們的主要區(qū)別是HashMap是非線程安全的。ConcurrentHashMap是線程安全的。

并發(fā)下可以使用ConcurrentHashMap和HashTable,他們的主要區(qū)別是:

1.ConcurrentHashMap的hash計(jì)算公式:(key.hascode()^ (key.hascode()>>> 16)) & 0x7FFFFFFF

?HashTable的hash計(jì)算公式:key.hascode()& 0x7FFFFFFF

2.HashTable存儲(chǔ)方式都是鏈表+數(shù)組,數(shù)組里面放的是當(dāng)前hash的第一個(gè)數(shù)據(jù),鏈表里面放的是hash沖突的數(shù)據(jù)

ConcurrentHashMap是數(shù)組+鏈表+紅黑樹

3.默認(rèn)容量都是16,負(fù)載因子是0.75。就是當(dāng)hashmap填充了75%的busket是就會(huì)擴(kuò)容,最小的可能性是(16*0.75),一般為原內(nèi)存的2倍

4.線程安全的保證:HashTable是在每個(gè)操作方法上面加了synchronized來達(dá)到線程安全,ConcurrentHashMap線程是使用CAS(compore and swap)來保證線程安全的

==================================================================

7.?? ?JAVA8的ConcurrentHashMap為什么放棄了分段鎖,有什么問題嗎,如果你來設(shè)計(jì),你如何設(shè)計(jì)。

jdk8 放棄了分段鎖而是用了Node鎖,減低鎖的粒度,提高性能,并使用CAS操作來確保Node的一些操作的原子性,取代了鎖。

但是ConcurrentHashMap的一些操作使用了synchronized鎖,而不是ReentrantLock,雖然說jdk8的synchronized的性能進(jìn)行了優(yōu)化,但是我覺得還是使用ReentrantLock鎖能更多的提高性能

==================================================================

8.?? 有順序的 Map 實(shí)現(xiàn)類?如果有,他們是怎么保證有序的 。?

順序的 Map 實(shí)現(xiàn)類:LinkedHashMap,TreeMap

LinkedHashMap 是基于元素進(jìn)入集合的順序或者被訪問的先后順序排序,TreeMap 則是基于元素的固有順序 (由 Comparator 或者 Comparable 確定)。

==================================================================

9.?? ?抽象類和接口的區(qū)別,類可以繼承多個(gè)類么,接口可以繼承多個(gè)接口么,類可以實(shí)現(xiàn)多個(gè)接口么。

抽象類和接口的區(qū)別:

1.抽象類可以有自己的實(shí)現(xiàn)方法,接口在jdk8以后也可以有自己的實(shí)現(xiàn)方法(default)

2.抽象類的抽象方法是由非抽象類的子類實(shí)現(xiàn),接口的抽象方法有接口的實(shí)現(xiàn)類實(shí)現(xiàn)

3.接口不能有私有的方法跟對(duì)象,抽象類可以有自己的私有的方法跟對(duì)象

類不可以繼承多個(gè)類,接口可以繼承多個(gè)接口,類可以實(shí)現(xiàn)多個(gè)接口

==================================================================

10.?? ?繼承和聚合的區(qū)別在哪

繼承:指的是一個(gè)類(稱為子類、子接口)繼承另外的一個(gè)類(稱為父類、父接口)的功能,并可以增加它自己的新功能的能力,繼承是類與類或者接口與接口之間最常見的關(guān)系;在Java中此類關(guān)系通過關(guān)鍵字extends明確標(biāo)識(shí),在設(shè)計(jì)時(shí)一般沒有爭議性;

聚合:聚合是關(guān)聯(lián)關(guān)系的一種特例,他體現(xiàn)的是整體與部分、擁有的關(guān)系,即has-a的關(guān)系,此時(shí)整體與部分之間是可分離的,他們可以具有各自的生命周期,部分可以屬于多個(gè)整體對(duì)象,也可以為多個(gè)整體對(duì)象共享;比如計(jì)算機(jī)與CPU、公司與員工的關(guān)系等;表現(xiàn)在代碼層面,和關(guān)聯(lián)關(guān)系是一致的,只能從語義級(jí)別來區(qū)分;

==================================================================

11.?? ?講講你理解的nio。他和bio的區(qū)別是啥,談?wù)剅eactor模型。

BIO:同步阻塞式IO,服務(wù)器實(shí)現(xiàn)模式為一個(gè)連接一個(gè)線程,即客戶端有連接請(qǐng)求時(shí)服務(wù)器端就需要啟動(dòng)一個(gè)線程進(jìn)行處理,如果這個(gè)連接不做任何事情會(huì)造成不必要的線程開銷,當(dāng)然可以通過線程池機(jī)制改善。

NIO:同步非阻塞式IO,服務(wù)器實(shí)現(xiàn)模式為一個(gè)請(qǐng)求一個(gè)線程,即客戶端發(fā)送的連接請(qǐng)求都會(huì)注冊(cè)到多路復(fù)用器上,多路復(fù)用器輪詢到連接有I/O請(qǐng)求時(shí)才啟動(dòng)一個(gè)線程進(jìn)行處理。

reactor模型:反應(yīng)器模式(事件驅(qū)動(dòng)模式):當(dāng)一個(gè)主體發(fā)生改變時(shí),所有的屬體都得到通知,類似于觀察者模式。

==================================================================

12.?? ?反射的原理,反射創(chuàng)建類實(shí)例的三種方式是什么。

反射的原理:如果知道一個(gè)類的名稱/或者它的一個(gè)實(shí)例對(duì)象, 就能把這個(gè)類的所有方法和變量的信息(方法名,變量名,方法,修飾符,類型,方法參數(shù)等等所有信息)找出來。

反射創(chuàng)建類實(shí)例的三種方式:

1.Class.forName("com.A");

2.new A().getClass();

3.A.class;

==================================================================

13.?? ?反射中,Class.forName和ClassLoader區(qū)別。

class.forName()除了將類的.class文件加載到j(luò)vm中之外,還會(huì)對(duì)類進(jìn)行解釋,執(zhí)行類中的static塊。

classLoader只干一件事情,就是將.class文件加載到j(luò)vm中,不會(huì)執(zhí)行static中的內(nèi)容,只有在newInstance才會(huì)去執(zhí)行static塊。

==================================================================

Java的動(dòng)態(tài)代理(dynamic proxy)

什么是動(dòng)態(tài)代理(dynamic proxy)

動(dòng)態(tài)代理(以下稱代理),利用Java的反射技術(shù)(Java Reflection),在運(yùn)行時(shí)創(chuàng)建一個(gè)實(shí)現(xiàn)某些給定接口的新類(也稱“動(dòng)態(tài)代理類”)及其實(shí)例(對(duì)象)

(Using Java Reflection to create dynamic implementations of interfaces at runtime)。

代理的是接口(Interfaces),不是類(Class),更不是抽象類。


動(dòng)態(tài)代理有什么用

解決特定問題:一個(gè)接口的實(shí)現(xiàn)在編譯時(shí)無法知道,需要在運(yùn)行時(shí)才能實(shí)現(xiàn)

實(shí)現(xiàn)某些設(shè)計(jì)模式:適配器(Adapter)或修飾器(Decorator)

面向切面編程:如AOP in Spring

14.?? ?描述動(dòng)態(tài)代理的幾種實(shí)現(xiàn)方式,分別說出相應(yīng)的優(yōu)缺點(diǎn)。


動(dòng)態(tài)代理有兩種實(shí)現(xiàn)方式,分別是:jdk動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理

jdk動(dòng)態(tài)代理的前提是目標(biāo)類必須實(shí)現(xiàn)一個(gè)接口,代理對(duì)象跟目標(biāo)類實(shí)現(xiàn)一個(gè)接口,從而避過虛擬機(jī)的校驗(yàn)。

cglib動(dòng)態(tài)代理是繼承并重寫目標(biāo)類,所以目標(biāo)類和方法不能被聲明成final。

==================================================================

15.?? ?動(dòng)態(tài)代理與cglib實(shí)現(xiàn)的區(qū)別。

動(dòng)態(tài)代理有兩種實(shí)現(xiàn)方式,分別是:jdk動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理

jdk動(dòng)態(tài)代理的前提是目標(biāo)類必須實(shí)現(xiàn)一個(gè)接口,代理對(duì)象跟目標(biāo)類實(shí)現(xiàn)一個(gè)接口,從而避過虛擬機(jī)的校驗(yàn)。

cglib動(dòng)態(tài)代理是繼承并重寫目標(biāo)類,所以目標(biāo)類和方法不能被聲明成final。

==================================================================

16.?? ?為什么cglib方式可以對(duì)接口實(shí)現(xiàn)代理。

cglib動(dòng)態(tài)代理是繼承并重寫目標(biāo)類,所以目標(biāo)類和方法不能被聲明成final。而接口是可以被繼承的。

==================================================================

17.?? ?final的用途。

1.final修飾的對(duì)象不能被修改;

2.final修飾的類不能被繼承;

3.final修飾的方法不能被重寫;

==================================================================

18.?? ?寫出三種單例模式實(shí)現(xiàn)。

?餓漢式


public class Singleton1 {

??? /*

??? * 餓漢式是在聲明的時(shí)候就已經(jīng)初始化Singleton1,確保了對(duì)象的唯一性

??? *

??? * 聲明的時(shí)候就初始化對(duì)象會(huì)浪費(fèi)不必要的資源

??? * */

??? private static Singleton1 instance = new Singleton1();

??? private Singleton1() {

??? }

??? // 通過靜態(tài)方法或枚舉返回單例對(duì)象

??? public Singleton1 getInstance() {

??????? return instance;

??? }

}

懶漢式

public class Singleton2 {

??? private static Singleton2 instance;

??? private Singleton2() {

??? }

??? /*

??? * getInstance 添加了synchronized 關(guān)鍵字,,也就是說 getInstance 是一個(gè)同步方法,

??? * 這就是懶漢式在多線程中保持唯一性的方式

??? *

??? * 懶漢式存在的問題是,即是instance已經(jīng)被創(chuàng)建,每次調(diào)用getInstance方法還是會(huì)同步,這樣就會(huì)浪費(fèi)一些不必要的資源

??? * */

??? public static synchronized Singleton2 getInstance() {

??????? if (instance == null) {

??????????? instance = new Singleton2();

??????? }

??????? return instance;

??? }

}


==================================================================

19.?? ?如何在父類中為子類自動(dòng)完成所有的hashcode和equals實(shí)現(xiàn)?這么做有何優(yōu)劣。

父類的equals不一定滿足子類的equals需求。比如所有的對(duì)象都繼承Object,默認(rèn)使用的是Object的equals方法,在比較兩個(gè)對(duì)象的時(shí)候,是看他們是否指向同一個(gè)地址。

但是我們的需求是對(duì)象的某個(gè)屬性相同,就相等了,而默認(rèn)的equals方法滿足不了當(dāng)前的需求,所以我們要重寫equals方法。

如果重寫了equals 方法就必須重寫hashcode方法,否則就會(huì)降低map等集合的索引速度。

==================================================================

20.?? ?請(qǐng)結(jié)合OO設(shè)計(jì)理念,談?wù)勗L問修飾符public、private、protected、default在應(yīng)用設(shè)計(jì)中的作用。

OO設(shè)計(jì)理念:封裝、繼承、多態(tài)

封裝,也就是把客觀事物封裝成抽象的類,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對(duì)象操作,對(duì)不可信的進(jìn)行信息隱藏。所以我們可以通過public、private、protected、default 來進(jìn)行訪問控制

關(guān)鍵字類內(nèi)部本包子類外部包

public?√√√√

protected√√√×

default?√√××

private√×××

java訪問控制符的含義和使用情況

==================================================================?

21.?? ?深拷貝和淺拷貝區(qū)別。

淺拷貝只拷貝指針,深拷貝就是拷貝他的值,重新生成的對(duì)像。

==================================================================

22.?? ?數(shù)組和鏈表數(shù)據(jù)結(jié)構(gòu)描述,各自的時(shí)間復(fù)雜度。

數(shù)組是將元素在內(nèi)存中連續(xù)存放,由于每個(gè)元素占用內(nèi)存相同,可以通過下標(biāo)迅速訪問數(shù)組中任何元素。

鏈表恰好相反,鏈表中的元素在內(nèi)存中不是順序存儲(chǔ)的,而是通過存在元素中的指針聯(lián)系到一起。

訪問數(shù)組中第 n 個(gè)數(shù)據(jù)的時(shí)間花費(fèi)是 O(1) 但是要在數(shù)組中查找一個(gè)指定的數(shù)據(jù)則是 O(N) 。當(dāng)向數(shù)組中插入或者刪除數(shù)據(jù)的時(shí)候,最好的情況是在數(shù)組的末尾進(jìn)行操作,時(shí)間復(fù)雜度是 O(1) ,但是最壞情況是插入或者刪除第一個(gè)數(shù)據(jù),時(shí)間復(fù)雜度是 O(N) 。在數(shù)組的任意位置插入或者刪除數(shù)據(jù)的時(shí)候,后面的數(shù)據(jù)全部需要移動(dòng),移動(dòng)的數(shù)據(jù)還是和數(shù)據(jù)個(gè)數(shù)有關(guān)所以總體的時(shí)間復(fù)雜度仍然是 O(N) 。?

?在鏈表中查找第 n 個(gè)數(shù)據(jù)以及查找指定的數(shù)據(jù)的時(shí)間復(fù)雜度是 O(N) ,但是插入和刪除數(shù)據(jù)的時(shí)間復(fù)雜度是 O(1)

==================================================================

23.?? ?error和exception的區(qū)別,CheckedException,RuntimeException的區(qū)別。

Error(錯(cuò)誤)表示系統(tǒng)級(jí)的錯(cuò)誤和程序不必處理的異常,是java運(yùn)行環(huán)境中的內(nèi)部錯(cuò)誤或者硬件問題。比如:內(nèi)存資源不足等。對(duì)于這種錯(cuò)誤,程序基本無能為力,除了退出運(yùn)行外別無選擇,它是由Java虛擬機(jī)拋出的。

Exception(違例)表示需要捕捉或者需要程序進(jìn)行處理的異常,它處理的是因?yàn)槌绦蛟O(shè)計(jì)的瑕疵而引起的問題或者在外的輸入等引起的一般性問題,是程序必須處理的。

Exception又分為運(yùn)行時(shí)異常,受檢查異常。

RuntimeException(運(yùn)行時(shí)異常),表示無法讓程序恢復(fù)的異常,導(dǎo)致的原因通常是因?yàn)閳?zhí)行了錯(cuò)誤的操作,建議終止程序,因此,編譯器不檢查這些異常。

CheckedException(受檢查異常),是表示程序可以處理的異常,也即表示程序可以修復(fù)(由程序自己接受異常并且做出處理), 所以稱之為受檢查異常。

==================================================================

24.?? ?請(qǐng)列出5個(gè)運(yùn)行時(shí)異常。

NullPointerException

IndexOutOfBoundsException

ClassCastException

ArrayStoreException

BufferOverflowException

==================================================================

25.?? ?在自己的代碼中,如果創(chuàng)建一個(gè)java.lang.String對(duì)象,這個(gè)對(duì)象是否可以被類加載器加載?為什么。

不可以,雙親委派模式會(huì)保證父類加載器先加載類,就是BootStrap(啟動(dòng)類)加載器加載jdk里面的java.lang.String類,而自定義的java.lang.String類永遠(yuǎn)不會(huì)被加載到

==================================================================

26.?? ?說一說你對(duì)java.lang.Object對(duì)象中hashCode和equals方法的理解。在什么場景下需要重新實(shí)現(xiàn)這兩個(gè)方法。

父類的equals不一定滿足子類的equals需求。比如所有的對(duì)象都繼承Object,默認(rèn)使用的是Object的equals方法,在比較兩個(gè)對(duì)象的時(shí)候,是看他們是否指向同一個(gè)地址。

但是我們的需求是對(duì)象的某個(gè)屬性相同,就相等了,而默認(rèn)的equals方法滿足不了當(dāng)前的需求,所以我們要重寫equals方法。

如果重寫了equals 方法就必須重寫hashcode方法,否則就會(huì)降低map等集合的索引速度。

==================================================================

27.?? ?在jdk1.5中,引入了泛型,泛型的存在是用來解決什么問題。

泛型的好處是在編譯的時(shí)候檢查類型安全,并且所有的強(qiáng)制轉(zhuǎn)換都是自動(dòng)和隱式的,提高代碼的重用率。

==================================================================

28.??? 有沒可能 2個(gè)不相等的對(duì)象有同hashcode。

有可能,最簡單的方法,百分百實(shí)現(xiàn)的方式就是重寫hascode();

==================================================================

29.??? Java中的HashSet內(nèi)部是如何工作的。

public HashSet() {map =new HashMap<>();}

默認(rèn)使用的是HaseMap;

==================================================================

30.??? 什么是序列化,怎么序列化,為什么序列化,反序列化會(huì)遇到什么問題,如何解決。

序列化是一種用來處理對(duì)象流的機(jī)制 ,所謂對(duì)象流就是將對(duì)象的內(nèi)容進(jìn)行流化。

序列化是為了解決在對(duì)對(duì)象流進(jìn)行讀寫操作時(shí)所引發(fā)的問題。

序列化的實(shí)現(xiàn):將需要被序列化的類實(shí)現(xiàn)Serializable接口,該接口沒有需要實(shí)現(xiàn)的方法,implements Serializable只是為了標(biāo)注該對(duì)象是可被序列化的,然后使用一個(gè)輸出流(如:FileOutputStream)來構(gòu)造一個(gè)ObjectOutputStream(對(duì)象流)對(duì)象,接著,使用ObjectOutputStream對(duì)象的writeObject(Object obj)方法就可以將參數(shù)為obj的對(duì)象寫出(即保存其狀態(tài)),要恢復(fù)的話則用輸入流;


線程池的作用:

線程池作用就是限制系統(tǒng)中執(zhí)行線程的數(shù)量。

根 據(jù)系統(tǒng)的環(huán)境情況,可以自動(dòng)或手動(dòng)設(shè)置線程數(shù)量,達(dá)到運(yùn)行的最佳效果;少了浪費(fèi)了系統(tǒng)資源,多了造成系統(tǒng)擁擠效率不高。用線程池控制線程數(shù)量,其他線程排 隊(duì)等候。一個(gè)任務(wù)執(zhí)行完畢,再從隊(duì)列的中取最前面的任務(wù)開始執(zhí)行。若隊(duì)列中沒有等待進(jìn)程,線程池的這一資源處于等待。當(dāng)一個(gè)新任務(wù)需要運(yùn)行時(shí),如果線程池 中有等待的工作線程,就可以開始運(yùn)行了;否則進(jìn)入等待隊(duì)列。

為什么要用線程池:

1.減少了創(chuàng)建和銷毀線程的次數(shù),每個(gè)工作線程都可以被重復(fù)利用,可執(zhí)行多個(gè)任務(wù)。

2.可以根據(jù)系統(tǒng)的承受能力,調(diào)整線程池中工作線線程的數(shù)目,防止因?yàn)橄倪^多的內(nèi)存,而把服務(wù)器累趴下(每個(gè)線程需要大約1MB內(nèi)存,線程開的越多,消耗的內(nèi)存也就越大,最后死機(jī))。

Java里面線程池的頂級(jí)接口是Executor,但是嚴(yán)格意義上講Executor并不是一個(gè)線程池,而只是一個(gè)執(zhí)行線程的工具。真正的線程池接口是ExecutorService。

比較重要的幾個(gè)類:

ExecutorService: 真正的線程池接口。

ScheduledExecutorService: 能和Timer/TimerTask類似,解決那些需要任務(wù)重復(fù)執(zhí)行的問題。

ThreadPoolExecutor: ExecutorService的默認(rèn)實(shí)現(xiàn)。

ScheduledThreadPoolExecutor: 繼承ThreadPoolExecutor的ScheduledExecutorService接口實(shí)現(xiàn),周期性任務(wù)調(diào)度的類實(shí)現(xiàn)。

要配置一個(gè)線程池是比較復(fù)雜的,尤其是對(duì)于線程池的原理不是很清楚的情況下,很有可能配置的線程池不是較優(yōu)的,因此在Executors類里面提供了一些靜態(tài)工廠,生成一些常用的線程池。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容