單例模式的應用
阿新 • • 發佈:2020-12-29
技術標籤:設計模式
概述
單例模式是一個類,主要作用是在全域性模式下生成唯一的一個類,為此在業務概念上,如果有些資料在系統中只應儲存一份,那就比較適合設計為單例類,比如日誌記錄類,Logger,或是全域性下唯一遞增ID號碼生成器
需求
有一個單例模型設計出來的唯一ID生成器,我們需要在高併發環境下測試這個唯一ID生成器是否真能生成唯一的ID
public class IdGeneratorScjc {
//建立你需要的類
private AtomicLong id = new AtomicLong();
private static IdGeneratorScjc instance;
//建構函式私有化
private IdGeneratorScjc(){
}
public static IdGeneratorScjc getInstance(){
if (instance==null){
synchronized (IdGeneratorScjc.class){
if (instance==null){
instance = new IdGeneratorScjc();
}
}
}
return instance;
}
public long getId(){
return id.getAndIncrement();
}
}
實現
我們想到的是多執行緒模擬下去模擬高併發的環境,那麼就需要一個多執行緒類,這個執行緒類能夠產生足夠多的執行緒,去訪問Controller方法,我們在控制檯觀察id,是否重複,不重複則說明單例模式起作用了
多執行緒類
public class ThreadTest{
//java模擬多執行緒高併發測試程式
static int count = 0;
int threadNum = 4;
int clientNum = 20000;
public static void main(String[] args) {
new ThreadTest().run();
}
public void run() {
// 建立ExecutorService執行緒池,threadNum個執行緒可以同時訪問
ExecutorService exec = Executors.newFixedThreadPool(threadNum);
// 模擬clientNum個客戶端訪問
final CountDownLatch doneSignal = new CountDownLatch(clientNum);
for (int i = 0; i < clientNum; i++) {
Runnable run = new Runnable() {
public void run() {
try {
URL url = new URL("http://localhost:8089/idGenerator/getId");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
int contentLength = urlConnection.getContentLength();
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
doneSignal.countDown();// 每呼叫一次countDown()方法,計數器減1
}
};
exec.execute(run);
}
}
}
controller類
@RequestMapping("getId")
public void getId(){
long id = IdGeneratorScjc.getInstance().getId();
System.out.println("id:"+id);
}
結果,沒有問題,算是單例模式的一個簡單應用吧,多執行緒真滴好用