=================================Quartz多任務阻塞原因================================== 轉自:http://blog.csdn.net/hongweigg/article/details/6188238
Quartz 調度器以多線程的方式執行調度任務JobDetail,缺省線程池大小爲10,也就是說若調度器中已有10個Job在工作(線程沒有結束),那麼即使有JobDetail到了被觸發的時間,新的JobDetail不會被執行,也就是說阻塞的條件是,調度器中正在運行的JobDetail數量達到了設定值10。
舉一個具體的例子:
a. 單一Job
配置:
JobA 觸發時間爲 每秒運行一次,每個Job執行時間爲30秒
運行:
1、 10個JobA將連續啓動
2、 到第10個JobA啓動後,線程池中所有線程被耗盡,調度器出現了阻塞,即沒有新的JobA啓動,儘管設置爲每秒執行一次。
3、30秒後,將有1個以上JobA執行完畢,在短時間內,新的10個JobA又被啓動,再次進入2的阻塞狀態
2狀態可以稱做調度器阻塞狀態,沒有新的Job能執行,導致一些諸如定時讀取數據的操作無法繼續下去。除非有JobA執行完畢,新的JobA才能被執行。實際運行中,假設調度器中有一個JobA線程的執行時間大於兩次啓動間隔,則經過若干次操作後,將耗盡所有10個線程資源,導致其他的調度任務阻塞。
b. 多個Job(無狀態Job)
在這個測試中,可以有多種不同的Job(無狀態Job),但它們均共享這10個線程,任何一個Job 線程執行時間大於兩次啓動間隔均有可能導致調度器被阻塞。例如:
配置:
JobA 觸發時間爲 每秒運行一次,每個Job執行時間爲30秒;JobB 觸發時間爲每秒運行一次,每次執行時間小於1秒
運行:
1。JobA和JobB相繼啓動
2。幾秒鐘後JobA數量達到10,其間JobB被執行若干次,則新的JobA和JobB均不能被啓動,調度器進入阻塞狀態
3。30秒後,JobA(0-9)相繼執行完畢,新的JobA和JobB均有機會被重新啓動,短時間內,再次進入2的阻塞狀態
如何解決調度器阻塞問題?
1、 延長可能需要較長時間執行的JOB的時間間隔,假設Job執行時間最大時間爲t1, 兩次任務執行間隔調度時間爲d1, 則d1>t1
2、 使用有狀態調度任務StatefulJob代替沒有狀態的Job. 對於要求執行間隔時間儘可能短,又不希望造成阻塞的比較適合。可以同時有無狀態的調度任務JobA,和有狀態的調度任務JobB,JobB堵塞後不會對JobA造成影響,即讀報文的任務阻塞了,不會對調度器中其他任務造成影響,同時JobA執行完後,可再次繼續下一個任務。
如果JobA執行時間較長的話,可能造成JobA始終佔用一個線程資源。
3、注意:一個調度器中如果有很多個Job(JobA,JobB,JobC...),其中有一個很容易堵塞,則該Job也會造成其他的Job阻塞
線程池大小配置在org.quartz下的quartz.properties文件中
org.quartz.threadPool.threadCount = 10
如若要修改線程池的大小,可以修改該文件中的 org.quartz.threadPool.threadCount值。亦可建一org.quartz包,包下放置quartz.properties文件,覆蓋掉quartz.jar中的配置
但是,修改線程池的大小並不能解決調度器阻塞問題,因爲資源消耗的速度不及資源釋放的速度時,資源就會被耗盡。
=========================================併發問題====================================
轉自:http://blog.csdn.net/flyflyflyflyflyfly/article/details/41870489
1、quartz默認是多線程的,如果執行任務的對象不是單例的,則每個線程都會產生任務對象,這些任務對象的同時執行可能會導致併發問題
2、quartz.properties配置文件是可以自己建的,建好後通過scheduler = new StdSchedulerFactory(QUARTZ_CONFIG_PATH).getScheduler();即可生成按照自己配置文件配置的Scheduler
3、concurrent字段的含義是指如果一個線程的任務沒執行完,concurrent=true表示新開一個線程,concurrent=flase表示等待當前線程執行完畢,跟單線程、多線程沒關係
4、順便說下類鎖、對象鎖的問題,加類鎖,即靜態鎖,就是一個類一個鎖,該類產生的所有對象在多線程訪問時,同時只能一個線程訪問加了synchronized的代碼塊,而對象鎖則是,一個對象一個鎖,多線程同時只有一個線程訪問該對象加synchronized的代碼塊,跟其他對象無關,其他對象也同時可以有線程訪問