檢視ScheduledExecutorService介面裏的scheduleWithFixedDelay方法的jdk文件,有描述如下: If any execution of the task encounters an exception, subsequent executions are suppressed. 如果在任務的執行中遇到異常,後續執行被取消。 ScheduledThreadPoolExecutor的最優實踐:將所有執行程式碼用try-catch包裹。
是的。
public class SynTest {
public void synBlock() {
synchronized (this) {
System.out.println("lagou");
}
}
}
//javap -verbose SynTest.class,就可以看到對應的反彙編內容。
public void synBlock();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=1
0: aload_0
1: dup
2: astore_1
3: monitorenter
4: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
7: ldc #3 // String lagou
9: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
12: aload_1
13: monitorexit
14: goto 22
17: astore_2
18: aload_1
19: monitorexit
20: aload_2
21: athrow
22: return
synchronized 程式碼塊實際上多了 monitorenter 和 monitorexit 指令,的第3、13、19行指令分別對應的是 monitorenter 和 monitorexit。這裏有一個 monitorenter,卻有兩個 monitorexit 指令的原因是:JVM要保證每個monitorenter必須有與之對應的monitorexit,monitorenter指令被插入到同步程式碼塊的開始位置,而monitorexit需要插入到方法正常結束處和異常處兩個地方,這樣就可以保證拋異常的情況下也能釋放鎖。
public synchronized void synMethod() {
}
//對應的反彙編指令如下所示。
public synchronized void synMethod();
descriptor: ()V
flags: ACC_PUBLIC, ACC_SYNCHRONIZED
Code:
stack=0, locals=1, args_size=1
0: return
LineNumberTable:
line 16: 0
可以看出,被synchronized修飾的方法會flags裏面有一個ACC_SYNCHRONIZED標誌。當某個執行緒要存取方法的時候,會首先檢查方法是否有SCC_SYNCHRONIZED標誌,如果有則需要先獲得monitor鎖(如果不是static修飾,就獲取物件鎖,如果是static修飾就獲取類鎖),然後才能 纔能開始執行方法體,方法執行之後再釋放monitor鎖。
否,當有執行緒執行 tryLock() 方法的時候,一旦有執行緒釋放了鎖,那麼這個正在 tryLock 的執行緒就能獲取到鎖,即使設定的是公平鎖模式,即使在它之前已經有其他正在等待佇列中等待的執行緒,簡單地說就是 tryLock 可以插隊。
//看原始碼可知
public boolean tryLock() {
return sync.nonfairTryAcquire(1);
}
這裏呼叫的就是 nonfairTryAcquire(),表明瞭是不公平的,和鎖本身是否是公平鎖無關。
優點:各個執行緒公平平等,每個執行緒在等待一段時間後,總能有執行的機會。
缺點:在於整體執行速度更慢,吞吐量更小。
優點:在於整體執行速度更快,吞吐量更大。
缺點:可能產生執行緒飢餓問題,也就是說如果一直有執行緒插隊,那麼在等待佇列中的執行緒可能長時間得不到執行。
Kafka訊息發送時,
Kafka消費端消費時,Kafka在讀取訊息時會首先嚐試從OS的頁快取中讀取,如果命中便把訊息經頁快取直接發送到網路的socket說。
概括的講:
------摘自《Apache kafka實戰》
BeanFactory - BeanFactory 就像一個包含 bean 集合的工廠類。它會在用戶端
要求時範例化 bean。
ApplicationContext - ApplicationContext 介面擴充套件了 BeanFactory 介面。它
在 BeanFactory 基礎上提供了一些額外的功能。
https://blog.csdn.net/cuipp0509/article/details/78544497
第一種:Consumer:消費型介面
void accept(T t);
第二種:Supplier:供給型介面
T get();
第三種:Function<T,R>:函數型介面
R apply(T t);
第四種:Predicate:斷言型介面
boolean test(T t)
//Consumer<T>:消費型介面
@Test
public void test1(){
happy(10000,(m)->System.out.println("你們哥喜歡大寶劍,每次消費:"+m+"元"));
}
public void happy(double money, Consumer<Double> consumer){
consumer.accept(money);
}
//Supplier<T>:供給型介面
@Test
public void test2(){
List<Integer> numList = getNumList(10, () -> (int) (Math.random() * 100));
for (Integer num:numList) {
System.out.println(num);
}
}
//需求:產生指定個數整數,並放入集閤中
public List<Integer> getNumList(int num, Supplier<Integer> supplier){
List<Integer> list=new ArrayList<>();
for (int i=0;i<num;i++){
Integer n = supplier.get();
list.add(n);
}
return list;
}
//Function<T,R>:函數型介面
@Test
public void test3(){
String newStr = strHandler("\t\t\t 我大北大荒威武 ", (str) -> str.trim());
System.out.println(newStr);
String subStr = strHandler("我大北大荒威武", (str) -> str.substring(2, 5));
System.out.println(subStr);
}
//需求:用於處理字串
public String strHandler(String str, Function<String,String> function){
return function.apply(str);
}
//Predicate<T>:斷言型介面
@Test
public void test4() {
List<String> list = Arrays.asList("hello", "atguigu", "Lambda", "www", "ok");
List<String> strList = filterStr(list, (s) -> s.length() > 3);
for (String str :strList) {
System.out.println(str);
}
}
//需求:將滿足條件的字串,放入集閤中
public List<String> filterStr(List<String> list, Predicate<String> predicate) {
List<String> strlist = new ArrayList<>();
for (String str : list) {
if (predicate.test(str)) {
strlist.add(str);
}
}
return strlist;
}
列舉被設計成是單例模式,即列舉型別會由JVM在載入的時候,範例化列舉物件,你在列舉類中定義了多少個就會範例化多少個,JVM爲了保證每一個列舉類元素的唯一範例,是不會允許外部進行new的,所以會把建構函式設計成private,防止使用者生成範例,破壞唯一性。
列舉型別是單例模式的。你需要範例化一次,然後再整個程式之中就可以呼叫他的方法和成員變數了。列舉型別使用單例模式是因爲他的值是固定的,不需要發生改變。
https://blog.csdn.net/songxinfeng1989/article/details/104021930
A. private
B. default
C. protected
D. public
Maven倉庫分爲:本地倉庫+遠端倉庫兩大類
遠端倉庫又分爲:中央倉庫+私服+其它公共遠端倉庫
Spring 提供了以下5種標準的事件:
(1)上下文更新事件(ContextRefreshedEvent):在呼叫ConfigurableApplicationContext 介面中的refresh()方法時被觸發。
(2)上下文開始事件(ContextStartedEvent):當容器呼叫ConfigurableApplicationContext的Start()方法開始/重新開始容器時觸發該事件。
(3)上下文停止事件(ContextStoppedEvent):當容器呼叫ConfigurableApplicationContext的Stop()方法停止容器時觸發該事件。
(4)上下文關閉事件(ContextClosedEvent):當ApplicationContext被關閉時觸發該事件。容器被關閉時,其管理的所有單例Bean都被銷燬。
(5)請求處理事件(RequestHandledEvent):在Web應用中,當一個http請求(request)結束觸發該事件。
如果一個bean實現了ApplicationListener介面,當一個ApplicationEvent 被髮布以後,bean會自動被通知。
1.自定義
2.DBCP開源連線池
3.C3P0開源連線池
Diff和Diff with previous version可以檢視某個檔案的修改資訊。
Repo-browser爲程式碼庫瀏覽器,
Show log 爲檢視日誌。
1、 儲存過程允許標準組件式程式設計
儲存過程在被建立以後可以在程式中被多次呼叫而不必重新編寫該儲存過程的SQL
語句而且數據庫專業人員可隨時對儲存過程進行修改但對應用程式原始碼毫無影響因
爲應用程式原始碼只包含儲存過程的呼叫語句從而極大地提高了程式的可移植性
2 、儲存過程能夠實現較快的執行速度
如果某一操作包含大量的Transaction-SQL 程式碼或分別被多次執行那麼儲存過程要
比批次處理的執行速度快很多因爲儲存過程是預編譯的在首次執行一個儲存過程時查
詢優化器對其進行分析優化並給出最終被存在系統表中的執行計劃而批次處理的Transaction-
SQL 語句在每次執行時都要進行編譯和優化因此速度相對要慢一些
3 、儲存過程能夠減少網路流量
對於同一個針對數據數據庫物件的操作如查詢修改如果這一操作所涉及到的
Transaction-SQL 語句被組織成一儲存過程那麼當在客戶計算機上呼叫該儲存過程時
網路中傳送的只是該呼叫語句否則將是多條SQL 語句從而大大增加了網路流量降
低網路負載
4、 儲存過程可被作爲一種安全機制 機製來充分利用
系統管理員通過對執行某一儲存過程的許可權進行限制從而能夠實現對相應的數據訪
問許可權的限制避免非授權使用者對數據的存取保證數據的安全
註解使用情況:Sql語句簡單時
xml系結使用情況:xml系結 (@RequestMap用來系結xml檔案)
當目錄merge出現confilct時,可以使用git ls-files -s檢視當前staged的object的狀態。可以看到test檔案出現了3個stage的狀態,分別爲1,2,3。而沒有出現衝突的檔案的stage狀態爲0. 針對存在confilict的檔案可以: git show :1:test # 檢視衝突檔案的common ancester版本 git show :2:test # 檢視本地branch中的版本 git show :3:test # 檢視遠端branch中的版本
通過在父模組中宣告dependencyManagement和pluginManagement, 然後讓子模組通過元素指定父模組,這樣子模組在定義依賴是就可以只定義groupId和artifactId,自動使用父模組的version,這樣統一整個專案的依賴的版本
git reset – filename 用於使用HEAD中的filename覆蓋index中的版本。
對於使用 upstart 的系統而言,編輯 /etc/default/docker 檔案,在其中的 DOCKER_OPTS 中設定加速器地址:
DOCKER_OPTS="–registry-mirror=https://registry.docker-cn.com"
重新啓動服務。
請在/etc/docker/daemon.json 中寫入如下內容(如果檔案不存在請新建該檔案)
{
"registry-mirrors": [
"https://registry.docker-cn.com"
]
}
注意,一定要保證該檔案符合 json 規範,否則 Docker 將不能啓動。
之後重新啓動服務。
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
docker rename goldberg mysqlberg
5種
Constraints,約束過濾器
Affnity,親和性過濾器
Dependency,依賴過濾器
Health filter,會根據節點狀態進行過濾
Ports filter,會根據埠的使用情況過濾
設定爲:600
錯誤,同步執行
阻塞佇列 | 非阻塞佇列 |
---|---|
ArrayBlockingQueue | ConcurrentLinkedQueue |
LinkedBlockingQueue | |
SynchronousQueue | |
DelayQueue | |
PriorityQueue | |
LinkedTransferQueue |
\ | 返回特殊值 | 拋異常 | 阻塞 |
---|---|---|---|
新增元素 | offer (true/false) | add (IllegalStateException) | put |
刪除首部元素 | poll (null) | remove (NoSuchElementException) | take |
返回首部元素 | peek (null) | element (NoSuchElementException) |
offer與poll還有對應的帶超時時間的過載方法
offer(E e, long tiomeout, TimeUnit unit)
poll(long tiomeout, TimeUnit unit)
++容量爲 0++ ,因爲SynchronousQueue不需要去持有元素,它所做的就是直接傳遞(direct handoff)。由於每次需要傳遞的時候,SynchronousQueue會把元素直接從生產者傳給消費者,在此期間並不需要做儲存。
所以它的peek()方法永遠返回 null
它的size()方法永遠返回 0
它的isEmpty()方法永遠返回 true
它成員變數裡只有一個Condition:
private final Condition notEmpty;
因爲它是無界佇列,所以只需要標識是否爲空的,不需要notFull,所以,它的put()方法永遠不會阻塞。
它是無界佇列,放入的元素必須實現Delayed介面,而Delayed介面又繼承了Comparable介面,所以自然就擁有了比較和排序的能力
public interface Delayed entendx Comparable<Delayed>{
// 返回的是「還剩下多久的延遲時間纔會被執行」
long getDelay(TimeUnit unit);
}
DelayQueue內部使用了PriorityQueue的能力來進行排序,減少了開發量,避免「重複造輪子」。
StringBuilder是採用字元陣列來存放實際數據,當呼叫append(**)方法時,會先判斷追加的字串長度是否大於當前StringBuilder內的字元陣列長度,如果沒有超過,則直接新增,如果超過了就需要擴容。
擴容是建立新的陣列,先嚐試擴容爲舊陣列的兩倍+2,在判斷一下,容量是否足夠,不夠就直接擴容到需要的容量大小。
因爲每次執行「+」操作時jvm都要new一個StringBuffer物件來處理字串的連線,這在涉及很多的字串連線操作時開銷會很大
日期格式化時,yyyy表示當天所在的年,而大寫的YYYY代表是week in which year(JDK7中引入的概念),意思是當天所在的周屬於的年份,一週從週日開始,週六結束,只要本週跨年,返回的就是下一年。
new SimpleDateFormat(「yyyy-MM-dd HH-mm-ss」)
- 表示月份是大寫的M;
- 表示分鐘則是小寫的m;
- 24小時制的是大寫的H;
- 12小時制的是小寫的h.
因爲直接使用toArray()無參方法的返回值是一個Object[]類,若強轉其它型別陣列將出現ClassCastException異常。
最優的方式就是這樣:
List<String> list = new Array<>();
list.add("liu");
list.add("yan");
list.add("bin");
String[] array = list.toArray(new String[0]);
說明:使用toArray(T[] array)帶參方法,陣列空間大小的length:
說明:在Array#addAll()方法的第一行程式碼即Object[] a = c.toArray(); 其中c爲輸入集合參數,如果爲null,則直接拋出異常。
asList的返回物件是Arrays內部類,並沒有實現集合的修改方法。Arrays.asList體現的是適配器模式,只是轉換介面,後臺的數據仍是陣列。
String[] str = new String[]{"ni","hao","ya"};
List list = Arrays.asList(str);
答案很明確——不是,ThreadLocal 並不是用來解決共用資源問題的。雖然 ThreadLocal 確實可以用於解決多執行緒情況下的執行緒安全問題,但其資源並不是共用的,而是每個執行緒獨享的。所以這道題其實是有一定陷阱成分在內的。
ThreadLocal 解決執行緒安全問題的時候,相比於使用「鎖」而言,換了一個思路,把資源變成了各執行緒獨享的資源,非常巧妙地避免了同步操作。具體而言,它可以在 initialValue 中 new 出自己執行緒獨享的資源,而多個執行緒之間,它們所存取的物件本身是不共用的,自然就不存在任何併發問題。這是 ThreadLocal 解決併發問題的最主要思路。
如果我們把放到 ThreadLocal 中的資源用 static 修飾,讓它變成一個共用資源的話,那麼即便使用了 ThreadLocal,同樣也會有執行緒安全問題。