(单例多例,枚举,动态代理,lombok)day23javaSE基础查漏补缺
單例多例,枚舉,動態代理,lombok
- 一級目錄
- 1.多線程下的懶漢模式
- 2.多例模式應用場景舉例:
- 3.線程池擴容和拒絕策略
- 4.用單例模式創建線程池,保證系統用的線程池是唯一的。
- 5.看一下線程池的擴容機制。
- 6.創建多少線程合適
- 7.線程池概述
- 8.枚舉是多例模式的簡寫(語法糖)。
- 9.枚舉一般默認空參構造方法。
- 10.裝飾者模式與動態代理的區別
- 11.動態代理代理的是接口,只能轉成接口,不能強轉成實現類
- 12.動態代理底層:采用的反射技術,會使用反射技術獲取到我們調用的方法,對方法進行攔截
- 13.lombok注解,會自動生成get/set啥的,并真實存在于class文件中。
- 14.return null和return啥區別
- 15.設計模式分類
- 16.多線程懶漢模式下:雙檢鎖為什么還要加volatile?
一級目錄
1.多線程下的懶漢模式
用同步方法。
Java多線程–單例模式的五種實現_makeliwei1的博客-CSDN博客_java多線程單例
2.多例模式應用場景舉例:
多并發請求環境下,系統需要為每個客戶端的獨立請求提供單獨服務的資源,但是系統總的開銷是有限的,系統在并發量很大時也不可能為所有的并發請求同時提供相應的資源,否則不但系統資源消耗量大而且非常耗時。這時就可以考慮使用池的概念,也即是一種多例模式的實現。具體的應用場景,比如數據庫連接池、EJB無狀態會話Bean的實例池
代碼實現上一般是提供一個容器類,也即是容納資源對象的池,對象池的一些屬性可以通過配置文件來配置,比如數據庫連接池中容納的Connection類型的對象數目的上限和下限、閑置連接超時時間等;然后每當應用程序請求數據庫連接時,先判斷池中有無空閑的連接,如有,即返回這個對象,如沒有,則新建一個連接對象,并放入連接池中進行管理
3.線程池擴容和拒絕策略
底層還是集合,擴容還是跟集合的擴容一樣,
他的目的是為了讓線程對象重復使用,不是完全意義上的多例模式。
多例子模式就是為了固定對象個數的。
4.用單例模式創建線程池,保證系統用的線程池是唯一的。
5.看一下線程池的擴容機制。
ThreadPoolExecutor線程池及線程擴展策略_u013276888的博客-CSDN博客_線程池擴容機制
6.創建多少線程合適
對于 CPU 密集型計算,多線程本質上是提升多核 CPU 的利用率,所以對于一個 4 核的 CPU,每個核一個線程,理論上創建 4 個線程就可以了,再多創建線程也只是增加線程切換的成本。所以,對于 CPU 密集型的計算場景,理論上“線程的數量 =CPU 核數”就是最合適的。不過在工程上,線程的數量一般會設置為“CPU 核數 +1”,這樣的話,當線程因為偶爾的內存頁失效或其他原因導致阻塞時,這個額外的線程可以頂上,從而保證 CPU 的利用率。
對于 I/O 密集型的計算場景,比如前面我們的例子中,如果 CPU 計算和 I/O 操作的耗時是 1:1,那么 2 個線程是最合適的。如果 CPU 計算和 I/O 操作的耗時是 1:2,那多少個線程合適呢?是 3 個線程,這樣 CPU 和 I/O 設備的利用率都達到了 100%。
核心*2
此方式使用的是下方第一個計算公式進行計算的。
計算公式如下:最佳線程數 =CPU 核數 * 期待CPU利用率* [ 1 +(I/O 耗時 / CPU 耗時)]
原文鏈接:https://blog.csdn.net/w5761499123/article/details/105906757
7.線程池概述
核心線程滿了,接下來進隊列,隊列也滿了,創建新線程,直到達到最大線程數,之后再超出,會進入拒絕rejectedExecution
8.枚舉是多例模式的簡寫(語法糖)。
獲取多個特定的對象的簡寫
9.枚舉一般默認空參構造方法。
10.裝飾者模式與動態代理的區別
裝飾者模式:
就是為了給裝飾者的方法增強,單純的是為了在裝飾者方法上增加其他功能。是繼承的一種替代方案,可以理解為 在不改變接口的前提下,動態擴展對象的功能
動態代理:
給一個對象提供一個代理對象,并有代理對象來控制對原有對象的引用;被代理的對象難以直接獲得或者是不想暴露給客戶端
11.動態代理代理的是接口,只能轉成接口,不能強轉成實現類
注意:必須使用代理人對象調用方法的功能
12.動態代理底層:采用的反射技術,會使用反射技術獲取到我們調用的方法,對方法進行攔截
13.lombok注解,會自動生成get/set啥的,并真實存在于class文件中。
14.return null和return啥區別
單寫return;結束無返回值方法。
return null結束有返回(對象)方法。
15.設計模式分類
創建型-高效創建對象
?簡單工廠(SimpleFactory)
?工廠方法(FactoryMethod)
?抽象工廠(Abstract Factory)
?創建者(Builder)
?原型(Prototype)
?單例(Singleton)
?多例(Multiton)
結構型-對象的組成和依賴關系
?外觀(Facade)
?適配器(Adapter)
?代理(Proxy)
?裝飾者(Decorator)
?橋(Bridge)
?組合(Composite)
?享元(Flyweight)
行為型-對象的行為
?模板方法(Template Method)
?觀察者(Observer)
?狀態(State)
?策略(Strategy)
?責任鏈(Chain of Responsibility)
?命令(Command)
?訪問者(Visitor)
?調停者(Mediator)
?備忘錄(Memento)
?迭代器(Iterator)
?解釋器(Interpreter)
16.多線程懶漢模式下:雙檢鎖為什么還要加volatile?
我們為什么在聲明MyObject對象的時候還要給它加上volatile關鍵字?我們在Double-Check下已經加入了synchronized關鍵字,既然synchronized已經起到了多線程下原子性、有序性、可見性的作用,為什么還要加volatile呢?要解決這個問題,我們需要深入了解volatile關鍵字的特性,它不僅可以使變量在多個線程之間可見,而且它還具有禁止JVM進行指令重排序的功能,具體請參見JVM–從volatile深入理解Java內存模型這篇文章。
首先,我們需要明白的是:創建一個對象可以分解為如下的3行偽代碼:
memory=allocate(); //1.分配對象的內存空間 ctorInstance(memory); //2.初始化對象 instance=memory; //3.設置instance指向剛分配的內存地址。//上面3行代碼中的2和3之間,可能會被重排序導致先3后2也就是說,myObject = new MyObject()這句話并不是一個原子性操作,在多線程環境下有可能出現非線程安全的情況。
現在我們先假設一下,如果此時不設置volatile關鍵字會發生什么。
假設兩個線程A、B,都是第一次調用該單例方法,線程A先執行myObject = new MyObject(),該構造方法是一個非原子操作,編譯后生成多條字節碼指令,由于JAVA的指令重排序,可能會先執行myObject的賦值操作,該操作實際只是在內存中開辟一片存儲對象的區域后直接返回內存的引用,之后myObject便不為空了,但是實際的初始化操作卻還沒有執行,如果就在此時線程B進入,就會看到一個不為空的但是不完整(沒有完成初始化)的MyObject對象,所以需要加入volatile關鍵字,禁止指令重排序優化,從而安全的實現單例。
因此我們以后應該記得,在使用Double-Check的時候,那個volatile至關重要。并不是可要可不要的。
原文鏈接:https://blog.csdn.net/championhengyi/article/details/77677393
總結
以上是生活随笔為你收集整理的(单例多例,枚举,动态代理,lombok)day23javaSE基础查漏补缺的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [js高手之路]html5 canvas
- 下一篇: android后台进程隐藏手段