1. 程式人生 > >java中程式碼執行速度問題

java中程式碼執行速度問題

可供程式利用的資源(記憶體、CPU時間、網路頻寬等)是有限的,優化的目的就是讓程式用盡可能少的資源完成預定的任務。優化通常包含兩方面的內容:減小程式碼的體積,提高程式碼的執行效率。本文討論的主要是如何提高程式碼的效率。
在Java程式中,效能問題的大部分原因並不在於Java語言,而是在於程式本身。養成好的程式碼編寫習慣非常重要,比如正確地、巧妙地運用java.lang.String類和java.util.Vector類,它能夠顯著地提高程式的效能。下面我們就來具體地分析一下這方面的問題。

1、     儘量指定類的final修飾符帶有final修飾符的類是不可派生的。在Java核心API中,有許多應用final的例子,例如java.lang.String。為String類指定final防止了人們覆蓋length()方法。另外,如果指定一個類為final,則該類所有的方法都是final。Java編譯器會尋找機會內聯(inline)所有的final方法(這和具體的編譯器實現有關)。此舉能夠使效能平均提高50% 。

2、     儘量重用物件。特別是String 物件的使用中,出現字串連線情況時應用StringBuffer 代替。由於系統不僅要花時間生成物件,以後可能還需花時間對這些物件進行垃圾回收和處理。因此,生成過多的物件將會給程式的效能帶來很大的影響。

3、     儘量使用區域性變數,呼叫方法時傳遞的引數以及在呼叫中建立的臨時變數都儲存在棧(Stack)中,速度較快。其他變數,如靜態變數、例項變數等,都在堆(Heap)中建立,速度較慢。另外,依賴於具體的編譯器/JVM,區域性變數還可能得到進一步優化。請參見《儘可能使用堆疊變數》。

4、     不要重複初始化變數   預設情況下,呼叫類的建構函式時, Java會把變數初始化成確定的值:所有的物件被設定成null,整數變數(byte、short、int、long)設定成0,float和double變數設定成0.0,邏輯值設定成false。當一個類從另一個類派生時,這一點尤其應該注意,因為用new關鍵詞建立一個物件時,建構函式鏈中的所有建構函式都會被自動呼叫。

5、     在JAVA + ORACLE 的應用系統開發中,java中內嵌的SQL語句儘量使用大寫的形式,以減輕ORACLE解析器的解析負擔。

6、     Java 程式設計過程中,進行資料庫連線、I/O流操作時務必小心,在使用完畢後,即使關閉以釋放資源。因為對這些大物件的操作會造成系統大的開銷,稍有不慎,會導致嚴重的後果。

7、     由於JVM的有其自身的GC機制,不需要程式開發者的過多考慮,從一定程度上減輕了開發者負擔,但同時也遺漏了隱患,過分的建立物件會消耗系統的大量記憶體,嚴重時會導致記憶體洩露,因此,保證過期物件的及時回收具有重要意義。JVM回收垃圾的條件是:物件不在被引用;然而,JVM的GC並非十分的機智,即使物件滿足了垃圾回收的條件也不一定會被立即回收。所以,建議我們在物件使用完畢,應手動置成null。

8、     在使用同步機制時,應儘量使用方法同步代替程式碼塊同步。

9、     儘量減少對變數的重複計算
例如:for(int i = 0;i < list.size; i ++) {
             …
}
應替換為:
for(int i = 0,int len = list.size();i < len; i ++) {
             …
}

10、儘量採用lazy loading 的策略,即在需要的時候才開始建立。
     例如:     String str = “aaa”;
             if(i == 1) {
                 list.add(str);
}
應替換為:
             if(i == 1) {
String str = “aaa”;
                 list.add(str);
}
11、慎用異常
異常對效能不利。丟擲異常首先要建立一個新的物件。Throwable介面的建構函式呼叫名為fillInStackTrace()的本地(Native)方法,fillInStackTrace()方法檢查堆疊,收集呼叫跟蹤資訊。只要有異常被丟擲,VM就必須調整呼叫堆疊,因為在處理過程中建立了一個新的物件。異常只能用於錯誤處理,不應該用來控制程式流程。

12、不要在迴圈中使用:
Try {
} catch() {
}
應把其放置在最外層。

13、StringBuffer 的使用:
         StringBuffer表示了可變的、可寫的字串。
有三個構造方法 :
StringBuffer ();             //預設分配16個字元的空間
StringBuffer (int size);   //分配size個字元的空間
StringBuffer (String str);   //分配16個字元+str.length()個字元空間
你可以通過StringBuffer的建構函式來設定它的初始化容量,這樣可以明顯地提升效能。這裡提到的建構函式是StringBuffer(int length),length引數表示當前的StringBuffer能保持的字元數量。你也可以使用ensureCapacity(int minimumcapacity)方法在StringBuffer物件建立之後設定它的容量。首先我們看看StringBuffer的預設行為,然後再找出一條更好的提升效能的途徑。
StringBuffer在內部維護一個字元陣列,當你使用預設的建構函式來建立StringBuffer物件的時候,因為沒有設定初始化字元長度,StringBuffer的容量被初始化為16個字元,也就是說預設容量就是16個字元。當StringBuffer達到最大容量的時候,它會將自身容量增加到當前的2倍再加2,也就是(2*舊值+2)。如果你使用預設值,初始化之後接著往裡面追加字元,在你追加到第16個字元的時候它會將容量增加到34(2*16+2),當追加到34個字元的時候就會將容量增加到70(2*34+2)。無論何事只要StringBuffer到達它的最大容量它就不得不建立一個新的字元陣列然後重新將舊字元和新字元都拷貝一遍――這也太昂貴了點。所以總是給StringBuffer設定一個合理的初始化容量值是錯不了的,這樣會帶來立竿見影的效能增益。
StringBuffer初始化過程的調整的作用由此可見一斑。所以,使用一個合適的容量值來初始化StringBuffer永遠都是一個最佳的建議。

14、合理的使用Java類 java.util.Vector。
簡單地說,一個Vector就是一個java.lang.Object例項的陣列。Vector與陣列相似,它的元素可以通過整數形式的索引訪問。但是,Vector型別的物件在建立之後,物件的大小能夠根據元素的增加或者刪除而擴充套件、縮小。請考慮下面這個向Vector加入元素的例子:
Object obj = new Object();
Vector v = new Vector(100000);
for(int I=0;
I<100000; I++) { v.add(0,obj); }

  除非有絕對充足的理由要求每次都把新元素插入到Vector的前面,否則上面的程式碼對效能不利。在預設建構函式中,Vector的初始儲存能力是10個元素,如果新元素加入時儲存能力不足,則以後儲存能力每次加倍。Vector類就象StringBuffer類一樣,每次擴充套件儲存能力時,所有現有的元素都要複製到新的儲存空間之中。下面的程式碼片段要比前面的例子快幾個數量級:
Object obj = new Object();
Vector v = new Vector(100000);
for(int I=0; I<100000; I++) { v.add(obj); }

  同樣的規則也適用於Vector類的remove()方法。由於Vector中各個元素之間不能含有“空隙”,刪除除最後一個元素之外的任意其他元素都導致被刪除元素之後的元素向前移動。也就是說,從Vector刪除最後一個元素要比刪除第一個元素“開銷”低好幾倍。

  假設要從前面的Vector刪除所有元素,我們可以使用這種程式碼:
for(int I=0; I<100000; I++)
{
 v.remove(0);
}

  但是,與下面的程式碼相比,前面的程式碼要慢幾個數量級:
for(int I=0; I<100000; I++)
{
 v.remove(v.size()-1);
}

  從Vector型別的物件v刪除所有元素的最好方法是:
v.removeAllElements();

  假設Vector型別的物件v包含字串“Hello”。考慮下面的程式碼,它要從這個Vector中刪除“Hello”字串:
String s = "Hello";
int i = v.indexOf(s);
if(I != -1) v.remove(s);

  這些程式碼看起來沒什麼錯誤,但它同樣對效能不利。在這段程式碼中,indexOf()方法對v進行順序搜尋尋找字串“Hello”,remove(s)方法也要進行同樣的順序搜尋。改進之後的版本是:
String s = "Hello";
int i = v.indexOf(s);
if(I != -1) v.remove(i);

  這個版本中我們直接在remove()方法中給出待刪除元素的精確索引位置,從而避免了第二次搜尋。一個更好的版本是:
String s = "Hello"; v.remove(s);

  最後,我們再來看一個有關Vector類的程式碼片段:
for(int I=0; I++;I < v.length)

  如果v包含100,000個元素,這個程式碼片段將呼叫v.size()方法100,000次。雖然size方法是一個簡單的方法,但它仍舊需要一次方法呼叫的開銷,至少JVM需要為它配置以及清除堆疊環境。在這裡,for迴圈內部的程式碼不會以任何方式修改Vector型別物件v的大小,因此上面的程式碼最好改寫成下面這種形式:
int size = v.size(); for(int I=0; I++;I<size)

  雖然這是一個簡單的改動,但它仍舊贏得了效能。畢竟,每一個CPU週期都是寶貴的。

15、當複製大量資料時,使用System.arraycopy()命令。

16、程式碼重構:增強程式碼的可讀性。
     例如:
public class ShopCart {
         private List carts ;
         …
         public void add (Object item) {
             if(carts == null) {
                 carts = new ArrayList();
}
crts.add(item);
}
public void remove(Object item) {
     if(carts. contains(item)) {
         carts.remove(item);
}
}
public List getCarts() {
     //返回只讀列表
     return Collections.unmodifiableList(carts);
}

//不推薦這種方式
//this.getCarts().add(item);
     }

17、不用new關鍵詞建立類的例項
用new關鍵詞建立類的例項時,建構函式鏈中的所有建構函式都會被自動呼叫。但如果一個物件實現了Cloneable介面,我們可以呼叫它的clone()方法。clone()方法不會呼叫任何類建構函式。
在使用設計模式(Design Pattern)的場合,如果用Factory模式建立物件,則改用clone()方法建立新的物件例項非常簡單。例如,下面是Factory模式的一個典型實現:
public static Credit getNewCredit() {
     return new Credit();
}
改進後的程式碼使用clone()方法,如下所示:
private static Credit BaseCredit = new Credit();
public static Credit getNewCredit() {
     return (Credit) BaseCredit.clone();
}
上面的思路對於陣列處理同樣很有用。

18、乘法和除法
考慮下面的程式碼:
for (val = 0; val < 100000; val +=5) {
alterX = val * 8; myResult = val * 2;
}
用移位操作替代乘法操作可以極大地提高效能。下面是修改後的程式碼:
for (val = 0; val < 100000; val += 5) {
alterX = val << 3; myResult = val << 1;
}
修改後的程式碼不再做乘以8的操作,而是改用等價的左移3位操作,每左移1位相當於乘以2。相應地,右移1位操作相當於除以2。值得一提的是,雖然移位操作速度快,但可能使程式碼比較難於理解,所以最好加上一些註釋。

19、在JSP頁面中關閉無用的會話。
     一個常見的誤解是以為session在有客戶端訪問時就被建立,然而事實是直到某server端程式呼叫HttpServletRequest.getSession(true)這樣的語句時才被建立,注意如果JSP沒有顯示的使用 <%@pagesession="false"%> 關閉session,則JSP檔案在編譯成Servlet時將會自動加上這樣一條語句HttpSession session = HttpServletRequest.getSession(true);這也是JSP中隱含的session物件的來歷。由於session會消耗記憶體資源,因此,如果不打算使用session,應該在所有的JSP中關閉它。
對於那些無需跟蹤會話狀態的頁面,關閉自動建立的會話可以節省一些資源。使用如下page指令:<%@ page session="false"%>

20、JDBC與I/O
如果應用程式需要訪問一個規模很大的資料集,則應當考慮使用塊提取方式。預設情況下,JDBC每次提取32行資料。舉例來說,假設我們要遍歷一個5000行的記錄集,JDBC必須呼叫資料庫157次才能提取到全部資料。如果把塊大小改成512,則呼叫資料庫的次數將減少到10次。
[p][/p]21、Servlet與記憶體使用
許多開發者隨意地把大量資訊儲存到使用者會話之中。一些時候,儲存在會話中的物件沒有及時地被垃圾回收機制回收。從效能上看,典型的症狀是使用者感到系統週期性地變慢,卻又不能把原因歸於任何一個具體的元件。如果監視JVM的堆空間,它的表現是記憶體佔用不正常地大起大落。
解決這類記憶體問題主要有二種辦法。第一種辦法是,在所有作用範圍為會話的Bean中實現HttpSessionBindingListener介面。這樣,只要實現valueUnbound()方法,就可以顯式地釋放Bean使用的資源。另外一種辦法就是儘快地把會話作廢。大多數應用伺服器都有設定會話作廢間隔時間的選項。另外,也可以用程式設計的方式呼叫會話的setMaxInactiveInterval()方法,該方法用來設定在作廢會話之前,Servlet容器允許的客戶請求的最大間隔時間,以秒計。

22、使用緩衝標記
一些應用伺服器加入了面向JSP的緩衝標記功能。例如,BEA的WebLogic Server從6.0版本開始支援這個功能,Open Symphony工程也同樣支援這個功能。JSP緩衝標記既能夠緩衝頁面片斷,也能夠緩衝整個頁面。當JSP頁面執行時,如果目標片斷已經在緩衝之中,則生成該片斷的程式碼就不用再執行。頁面級緩衝捕獲對指定URL的請求,並緩衝整個結果頁面。對於購物籃、目錄以及入口網站的主頁來說,這個功能極其有用。對於這類應用,頁面級緩衝能夠儲存頁面執行的結果,供後繼請求使用。

23、選擇合適的引用機制
在典型的JSP應用系統中,頁頭、頁尾部分往往被抽取出來,然後根據需要引入頁頭、頁尾。當前,在JSP頁面中引入外部資源的方法主要有兩種:include指令,以及include動作。
include指令:例如<%@ include file="copyright.html" %>。該指令在編譯時引入指定的資源。在編譯之前,帶有include指令的頁面和指定的資源被合併成一個檔案。被引用的外部資源在編譯時就確定,比執行時才確定資源更高效。
include動作:例如<jsp:include page="copyright.jsp" />。該動作引入指定頁面執行後生成的結果。由於它在執行時完成,因此對輸出結果的控制更加靈活。但時,只有當被引用的內容頻繁地改變時,或者在對主頁面的請求沒有出現之前,被引用的頁面無法確定時,使用include動作才合算。

24、及時清除不再需要的會話
為了清除不再活動的會話,許多應用伺服器都有預設的會話超時時間,一般為30分鐘。當應用伺服器需要儲存更多會話時,如果記憶體容量不足,作業系統會把部分記憶體資料轉移到磁碟,應用伺服器也可能根據“最近最頻繁使用”(Most Recently Used)演算法把部分不活躍的會話轉儲到磁碟,甚至可能丟擲“記憶體不足”異常。在大規模系統中,序列化會話的代價是很昂貴的。當會話不再需要時,應當及時呼叫HttpSession.invalidate()方法清除會話。HttpSession.invalidate()方法通常可以在應用的退出頁面呼叫。

25、不要將陣列宣告為:public static final 。

26、HashMap的遍歷效率討論
經常遇到對HashMap中的key和value值對的遍歷操作,有如下兩種方法:Map<String, String[]> paraMap = new HashMap<String, String[]>();
................//第一個迴圈
Set<String> appFieldDefIds = paraMap.keySet();
for (String appFieldDefId : appFieldDefIds) {
String[] values = paraMap.get(appFieldDefId);
......
}

//第二個迴圈
for(Entry<String, String[]> entry : paraMap.entrySet()){
String appFieldDefId = entry.getKey();
String[] values = entry.getValue();
.......
}

第一種實現明顯的效率不如第二種實現。
分析如下 Set<String> appFieldDefIds = paraMap.keySet(); 是先從HashMap中取得keySet

程式碼如下:
public Set<K> keySet() {
Set<K> ks = keySet;
return (ks != null ? ks : (keySet = new KeySet()));
}

private class KeySet extends AbstractSet<K> {
public Iterator<K> iterator() {
return newKeyIterator();
}
public int size() {
return size;
}
public boolean contains(Object o) {
return containsKey(o);
}
public boolean remove(Object o) {
return HashMap.this.removeEntryForKey(o) != null;
}
public void clear() {
HashMap.this.clear();
}
}
其實就是返回一個私有類KeySet, 它是從AbstractSet繼承而來,實現了Set介面。

再來看看for/in迴圈的語法
for(declaration : expression_r)
statement

在執行階段被翻譯成如下各式
for(Iterator<E> #i = (expression_r).iterator(); #i.hashNext();){
declaration = #i.next();
statement
}

因此在第一個for語句for (String appFieldDefId : appFieldDefIds) 中呼叫了HashMap.keySet().iterator() 而這個方法呼叫了newKeyIterator()

Iterator<K> newKeyIterator() {
return new KeyIterator();
}
private class KeyIterator extends HashIterator<K> {
public K next() {
return nextEntry().getKey();
}
}

所以在for中還是呼叫了
在第二個迴圈for(Entry<String, String[]> entry : paraMap.entrySet())中使用的Iterator是如下的一個內部類

private class EntryIterator extends HashIterator<Map.Entry<K,V>> {
public Map.Entry<K,V> next() {
return nextEntry();
}
}

此時第一個迴圈得到key,第二個迴圈得到HashMap的Entry
效率就是從迴圈裡面體現出來的第二個迴圈此致可以直接取key和value值
而第一個迴圈還是得再利用HashMap的get(Object key)來取value值

現在看看HashMap的get(Object key)方法
public V get(Object key) {
Object k = maskNull(key);
int hash = hash(k);
int i = indexFor(hash, table.length); //Entry[] table
Entry<K,V> e = table;
while (true) {
if (e == null)
return null;
if (e.hash == hash && eq(k, e.key))
return e.value;
         e = e.next;
}
}
其實就是再次利用Hash值取出相應的Entry做比較得到結果,所以使用第一中迴圈相當於兩次進入HashMap的Entry中
而第二個迴圈取得Entry的值之後直接取key和value,效率比第一個迴圈高。其實按照Map的概念來看也應該是用第二個迴圈好一點,它本來就是key和value的值對,將key和value分開操作在這裡不是個好選擇。

27、array(陣列) 和 ArryList的使用
array([]):最高效;但是其容量固定且無法動態改變;
ArrayList:容量可動態增長;但犧牲效率;
基於效率和型別檢驗,應儘可能使用array,無法確定陣列大小時才使用ArrayList!
ArrayList是Array的複雜版本
ArrayList內部封裝了一個Object型別的陣列,從一般的意義來說,它和陣列沒有本質的差別,甚至於ArrayList的許多方法,如Index、IndexOf、Contains、Sort等都是在內部陣列的基礎上直接呼叫Array的對應方法。
ArrayList存入物件時,拋棄型別資訊,所有物件遮蔽為Object,編譯時不檢查型別,但是執行時會報錯。
注:jdk5中加入了對泛型的支援,已經可以在使用ArrayList時進行型別檢查。
從這一點上看來,ArrayList與陣列的區別主要就是由於動態增容的效率問題了

28、儘量使用HashMap 和ArrayList ,除非必要,否則不推薦使用HashTable和Vector ,後者由於使用同步機制,而導致了效能的開銷。

29、StringBuffer 和StringBuilder的區別:
     java.lang.StringBuffer執行緒安全的可變字元序列。一個類似於 String 的字串緩衝區,但不能修改。StringBuilder。與該類相比,通常應該優先使用 java.lang.StringBuilder類,因為它支援所有相同的操作,但由於它不執行同步,所以速度更快。為了獲得更好的效能,在構造 StirngBuffer 或 StirngBuilder 時應儘可能指定它的容量。當然,如果你操作的字串長度不超過 16 個字元就不用了。 相同情況下使用 StirngBuilder 相比使用 StringBuffer 僅能獲得 10%-15% 左右的效能提升,但卻要冒多執行緒不安全的風險。而在現實的模組化程式設計中,負責某一模組的程式設計師不一定能清晰地判斷該模組是否會放入多執行緒的環境中執行,因此:除非你能確定你的系統的瓶頸是在 StringBuffer 上,並且確定你的模組不會執行在多執行緒模式下,否則還是用 StringBuffer 吧。

希望著篇文章對大家的學習有所幫助。

相關推薦

java程式碼執行速度問題

可供程式利用的資源(記憶體、CPU時間、網路頻寬等)是有限的,優化的目的就是讓程式用盡可能少的資源完成預定的任務。優化通常包含兩方面的內容:減小程式碼的體積,提高程式碼的執行效率。本文討論的主要是如何提高程式碼的效率。 在Java程式中,效能問題的大部分原因並不在於Jav

java程式碼執行順序(靜態程式碼塊、建構函式)

1、方法、塊對應靜態和普通兩個級別,如果不產生例項,就只執行靜態部分,所有關聯類中的靜態部分總先於非靜態(例項化)部分執行。 2、靜態部分:靜態變數初始化--靜態程式碼塊--main方法。 3、非靜態部分(物件例項化過程):成員變數初始化--非靜態程式碼塊---建構函式 4、父類先於子類。靜態部分:父類靜態

java 繼承程式碼執行順序(個人見解)

面試題 以下程式碼執行結果 public class Test { class Super{ int flag=1; Super(){ test(); } void test(){

Java程式碼執行順序

先上程式碼: 1.程式碼片段一: /** * @author szn25 */ public class Main { static { System.out.println("main.static!"); } public static int fun

C#託管的中間程式碼IL為什麼和機器程式碼執行速度一樣快,與Java對比

C#託管的中間程式碼IL為什麼和機器程式碼執行速度一樣快,IL是即時編譯的(JIT),java位元組碼是解釋型的。java會把所有的程式碼都編譯完,在下次執行時就不需要再去編譯已經編譯過的程式碼。微軟對編譯做了優化,JIT只編譯呼叫的程式碼,因為程式執行過程中,大部分程式碼都

程式碼說話:如何在Java實現執行

併發程式設計是Java語言的重要特性之一,“如何在Java中實現執行緒”是學習併發程式設計的入門知識,也是Java工程師面試必備的基礎知識。本文從執行緒說起,然後用程式碼說明如何在Java中實現執行緒。 一、什麼是執行緒? 執行緒是作業系統能夠進行運算排程的最小單位,它被包含在程序之中,是程序中的實際運作單位

java定時執行任務

views sch start bsp tails pri ted java file 現在項目中用到需要定時去檢查文件是否更新的功能。timer正好用於此處。 用法很簡單,new一個timer,然後寫一個timertask的子類即可。 代碼如下: [java] vie

Java停止執行

一.停止執行緒會帶來什麼? 對於單執行緒中,停止單執行緒就是直接使用關鍵字return或者break,但是在停止多執行緒時是讓執行緒在完成任務前去開啟另外一條執行緒,必須放棄當前任務,而這個過程是不可預測,所以必須去做好防備。 二.認識停止執行緒的幾個方法  2.1三個被棄用的

java執行緒一定快嗎?看完就知道!!!

理解上下文切換   即使是單核處理器也支援多執行緒執行程式碼,CPU通過每個執行緒分配CPU時間片來實現這個機制.時間片是CPU分配給多個執行緒的時間,因為時間片非常短,所以CPU通過不停的切換執行緒執行,讓我們感覺多個執行緒是同時執行的,時間片一般是幾十毫秒(ms).  

深入理解Java停止執行

一.停止執行緒會帶來什麼? 對於單執行緒中,停止單執行緒就是直接使用關鍵字return或者break,但是在停止多執行緒時是讓執行緒在完成任務前去開啟另外一條執行緒,必須放棄當前任務,而這個過程是不可預測,所以必須去做好防備。 二.認識停止執行緒的幾個方法  2.1三個被棄用的方法 &n

Java執行緒池及其實現類ThreadPoolExecutor

前言:像我們連線資料庫一樣,需要不斷地建立連線,銷燬連線,如果都是人為地一個個建立和銷燬的話會很費勁,所以就誕生了資料庫連線池,執行緒池的產生也是同樣的道理。 執行緒池預先建立了若干數量的執行緒,並且不能由使用者直接對執行緒的建立進行控制,在這個前提下重複使用固定或較為固定數目的執行緒來完成任務

【小家javaJava執行緒(父執行緒)與子執行緒的通訊和聯絡

相關閱讀 【小家java】java5新特性(簡述十大新特性) 重要一躍 【小家java】java6新特性(簡述十大新特性) 雞肋升級 【小家java】java7新特性(簡述八大新特性) 不溫不火 【小家java】java8新特性(簡述十大新特性) 飽受讚譽 【小家java】java9

【小家javaJava執行緒池,你真的用對了嗎?(教你用正確的姿勢使用執行緒池)

相關閱讀 【小家java】java5新特性(簡述十大新特性) 重要一躍 【小家java】java6新特性(簡述十大新特性) 雞肋升級 【小家java】java7新特性(簡述八大新特性) 不溫不火 【小家java】java8新特性(簡述十大新特性) 飽受讚譽 【小家java】java9

如何在JAVA建立執行緒池

ExecutorService 今天小編要分享的是關於執行緒池, 想必接觸到併發處理的朋友都有用到執行緒池, 當我們訪問伺服器的量達到伺服器一定量的時候, 比如幾百萬幾千萬,很容易造成伺服器崩掉, 如果使用執行緒進行併發處理,將使用的執行緒進行回收在使用,就減小了伺服器的壓力

程式碼執行順序 及 組合

一  類的名稱空間:   類中的程式碼在什麼時候執行的?  在例項化之前,也就是說在建立一個類時,類自己先給自己建立 建一塊空間,也就是公共的空間.(裡面會把靜態變數和__init__及方法方進去) 類中程式碼執行順序:(在例項化之前就執行了) 問題:一個類中可不可以沒有__i

Java 如何執行字串表示式?!

背景和簡介 在日常的開發中,偶爾會遇到執行字串表示式的情況,通常這樣的需求會對需求進行進一步分析,然後進行進一步 “特殊化”,最後直接寫到硬程式碼中,這樣做的話,就不太好擴充套件了;也有另外的處理方式是採用 Java 內建的 JavaScript 引擎等執行字串表示式,但是內建引擎也有弊端,比如頻繁執行片段

分享Java 如何執行字串表示式?

在日常的開發中,偶爾會遇到執行字串表示式的情況,通常這樣的需求會對需求進行進一步分析,然後進行進一步 “特殊化”,最後直接寫到硬程式碼中,這樣做的話,就不太好擴充套件了;也有另外的處理方式是採用 Java 內建的 JavaScript 引擎等執行字串表示式,但是內建引擎也有弊端,比如頻繁執行片段式的

Java併發】Java執行緒池

Java中的執行緒池 執行流程 執行緒池的建立 提交任務 關閉執行緒池 參考 執行流程 處理流程如下: execute()方法執行示意圖如下: 執行緒池的建立 corePoolSize:執行緒池

java程式碼塊的認知

  在以往面試題中,出現過很多次關於程式碼塊執行順序的題目,目前可算是搞清楚執行順序了。看以下程式碼:    package com.itcast.code; public class BlockTest { static{ System.out.println("我是Bl

java 執行

1.概念: 什麼是程序?   概念:在計算機中執行的軟體,是作業系統中最基礎的組成部分 。程序是容器,裡面裝的都是執行緒。 什麼是執行緒?   概念:就是執行在程序中的一段程式碼,是程序中最小組織單元。 注意:  1.一個程序中至少要有一個執行緒,該執行緒必須是主執行緒  2.一個程序中可以有多個執行緒