關注微信公眾號 架構技術之美 ,學習更多技術和學習資料,
文章目錄
- 一、String 字串常量
- 二、StringBuffer 字串變數
- 三、StringBuilder 字串變數
- 四、總結
一、String 字串常量
String 是
不可變物件,每次對 String 物件進行改變都會生成一個新的 String 物件,然后將指標指向新的 String 物件,故經常改變內容的字串最好不要用 String ,因為每次生成物件都會對系統性能產生影響,特別當記憶體中無參考物件多了以后, JVM 的 GC 就會開始作業,那速度就更加慢了,
package com.nobody.part01;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
/**
* @author Mr.nobody
* @Description 測驗String字串拼接性能
* @date 2020/9/17
*/
public class StringDemo {
// 請求總數
private static int CLIENT_COUNT = 10000;
// 并發執行緒數
private static int THREAD_COUNT = 500;
// 全域變數
private static String STRING = new String();
public static void main(String[] args) throws InterruptedException {
// 固定執行緒池
ExecutorService executorService = Executors.newFixedThreadPool(CLIENT_COUNT);
// 控制同一個時刻,只能有多少個執行緒同時運行指定代碼,即acquire和release之間的代碼
Semaphore semaphore = new Semaphore(THREAD_COUNT);
CountDownLatch countDownLatch = new CountDownLatch(CLIENT_COUNT);
long startTime = System.currentTimeMillis();
for (int i = 0; i < CLIENT_COUNT; i++) {
executorService.execute(() -> {
try {
semaphore.acquire();
STRING += "0";
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
});
}
// 等待所有請求執行完
countDownLatch.await();
// 關閉執行緒池
executorService.shutdown();
long endTime = System.currentTimeMillis();
System.out.println("String -- 總共耗時:" + (endTime - startTime) + "ms,字串長度:" + STRING.length());
}
}

二、StringBuffer 字串變數
StringBuffer 是
可變物件,每次對 StringBuffer 物件進行改變都會對StringBuffer 物件本身進行操作,而不是生成新的物件,再改變物件參考,如果 StringBuffer 物件在多執行緒環境下,特別是字串物件經常改變的情況下,推薦使用它 ,因為 StringBuffer 幾乎所有的方法都加了synchronized關鍵字,所以是執行緒安全的,但是性能會相對較差,
package com.nobody.part01;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
/**
* @author Mr.nobody
* @Description 測驗執行緒安全類StringBuffer
* @date 2020/9/17
*/
public class StringBufferDemo {
// 請求總數
private static int CLIENT_COUNT = 10000;
// 并發執行緒數
private static int THREAD_COUNT = 500;
// 全域變數,執行緒安全StringBuffer
private static StringBuffer STRINGBUFFER = new StringBuffer();
public static void main(String[] args) throws InterruptedException {
// 固定執行緒池
ExecutorService executorService = Executors.newFixedThreadPool(CLIENT_COUNT);
// 控制同一個時刻,只能有多少個執行緒同時運行指定代碼,即acquire和release之間的代碼
Semaphore semaphore = new Semaphore(THREAD_COUNT);
CountDownLatch countDownLatch = new CountDownLatch(CLIENT_COUNT);
long startTime = System.currentTimeMillis();
for (int i = 0; i < CLIENT_COUNT; i++) {
executorService.execute(() -> {
try {
semaphore.acquire();
STRINGBUFFER.append("0");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
});
}
// 等待所有請求執行完
countDownLatch.await();
// 關閉執行緒池
executorService.shutdown();
long endTime = System.currentTimeMillis();
System.out.println("StringBuffer -- 總共耗時:" + (endTime - startTime) + "ms,字串長度:" + STRINGBUFFER.length());
}
}

三、StringBuilder 字串變數
StringBuilder 一個
可變的字符序列,StringBuilder 提供一個與 StringBuffer 兼容的 API,但不保證同步(即執行緒不安全),該類被設計用作 StringBuffer 的一個簡易替換,用在字串緩沖區被單個執行緒使用的時候(這種情況很普遍),在堆疊封閉等執行緒安全的環境下(方法中的區域變數)應該首選 StringBuilder,
package com.nobody.part01;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
/**
* @author Mr.nobody
* @Description 測驗執行緒不安全類StringBuilder
* @date 2020/9/17
*/
public class StringBuilderDemo {
// 請求總數
private static int CLIENT_COUNT = 10000;
// 并發執行緒數
private static int THREAD_COUNT = 500;
// 全域變數,執行緒不安全StringBuilder
private static StringBuilder STRINGBUILDER = new StringBuilder();
public static void main(String[] args) throws InterruptedException {
// 固定執行緒池
ExecutorService executorService = Executors.newFixedThreadPool(CLIENT_COUNT);
// 控制同一個時刻,只能有多少個執行緒同時運行指定代碼,即acquire和release之間的代碼
Semaphore semaphore = new Semaphore(THREAD_COUNT);
CountDownLatch countDownLatch = new CountDownLatch(CLIENT_COUNT);
long startTime = System.currentTimeMillis();
for (int i = 0; i < CLIENT_COUNT; i++) {
executorService.execute(() -> {
try {
semaphore.acquire();
STRINGBUILDER.append("0");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
});
}
// 等待所有請求執行完
countDownLatch.await();
// 關閉執行緒池
executorService.shutdown();
long endTime = System.currentTimeMillis();
System.out.println("StringBuilder -- 總共耗時:" + (endTime - startTime) + "ms,字串長度:" + STRINGBUILDER.length());
}
}

四、總結
- 對于不可變字串或者字串內容改變少的情況,推薦 String,
- 字串物件可能會被多執行緒訪問,并且經常改變內容,推薦 StringBuffer,
- 在堆疊封閉等執行緒安全的環境下(方法中的區域變數)推薦 StringBuilder,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/82621.html
標籤:其他
上一篇:maven子模塊參考父模塊的properties檔案
下一篇:在CentOS7上,用遠程的Putty進行測驗,使用命令traceroute和mtr,結果都是回傳一跳,原因是?
