新的起點(diǎn) 新的開(kāi)始

          快樂(lè)生活 !

          (轉(zhuǎn))Java 5.0多線程編程(2)

          *1: 定義了幾個(gè)任務(wù)

          *2: 初始了任務(wù)執(zhí)行工具。任務(wù)的執(zhí)行框架將會(huì)在后面解釋。

          *3: 執(zhí)行任務(wù),任務(wù)啟動(dòng)時(shí)返回了一個(gè) Future 對(duì)象,如果想得到任務(wù)執(zhí)行的結(jié)果或者是異常可對(duì)這個(gè) Future 對(duì)象進(jìn)行操作。 Future 所含的值必須跟 Callable 所含的值對(duì)映,比如說(shuō)例子中 Future 對(duì)印 Callable

          *4: 任務(wù) 1 正常執(zhí)行完畢, future1.get() 會(huì)返回線程的值

          *5: 任務(wù) 2 在進(jìn)行一個(gè)死循環(huán),調(diào)用 future2.cancel(true) 來(lái)中止此線程。傳入的參數(shù)標(biāo)明是否可打斷線程, true 表明可以打斷。

          *6: 任務(wù) 3 拋出異常,調(diào)用 future3.get() 時(shí)會(huì)引起異常的拋出。

          ? 運(yùn)行 Executor 會(huì)有以下運(yùn)行結(jié)果:

          looping....

          Task done. //*1

          looping....

          looping....//*2

          looping....

          looping....

          looping....

          looping....

          Thread 2 terminated? :true //*3

          //*4

          java.util.concurrent.ExecutionException: java.lang.Exception: Callable terminated with Exception!

          ??????? at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:205)

          ??????? at java.util.concurrent.FutureTask.get(FutureTask.java:80)

          ??????? at concurrent.Executor.main(Executor.java:43)

          ??????? …….

          *1: 任務(wù) 1 正常結(jié)束

          *2: 任務(wù) 2 是個(gè)死循環(huán),這是它的打印結(jié)果

          *3: 指示任務(wù) 2 被取消

          *4: 在執(zhí)行 future3.get() 時(shí)得到任務(wù) 3 拋出的異常

          3:新的任務(wù)執(zhí)行架構(gòu)

          ?? 在 Java 5.0 之前啟動(dòng)一個(gè)任務(wù)是通過(guò)調(diào)用 Thread 類(lèi)的 start() 方法來(lái)實(shí)現(xiàn)的,任務(wù)的提于交和執(zhí)行是同時(shí)進(jìn)行的,如果你想對(duì)任務(wù)的執(zhí)行進(jìn)行調(diào)度或是控制同時(shí)執(zhí)行的線程數(shù)量就需要額外編寫(xiě)代碼來(lái)完成。 5.0 里提供了一個(gè)新的任務(wù)執(zhí)行架構(gòu)使你可以輕松地調(diào)度和控制任務(wù)的執(zhí)行,并且可以建立一個(gè)類(lèi)似數(shù)據(jù)庫(kù)連接池的線程池來(lái)執(zhí)行任務(wù)。這個(gè)架構(gòu)主要有三個(gè)接口和其相應(yīng)的具體類(lèi)組成。這三個(gè)接口是 Executor, ExecutorService ScheduledExecutorService ,讓我們先用一個(gè)圖來(lái)顯示它們的關(guān)系:

          ?

          ? 圖的左側(cè)是接口,圖的右側(cè)是這些接口的具體類(lèi)。注意 Executor 是沒(méi)有直接具體實(shí)現(xiàn)的。

          Executor 接口:

          是用來(lái)執(zhí)行 Runnable 任務(wù)的,它只定義一個(gè)方法:

          • execute(Runnable command) :執(zhí)行 Ruannable 類(lèi)型的任務(wù)

          ExecutorService 接口:

          ExecutorService 繼承了 Executor 的方法,并提供了執(zhí)行 Callable 任務(wù)和中止任務(wù)執(zhí)行的服務(wù),其定義的方法主要有:

          • submit(task) :可用來(lái)提交 Callable Runnable 任務(wù),并返回代表此任務(wù)的 Future 對(duì)象
          • invokeAll(collection of tasks) :批處理任務(wù)集合,并返回一個(gè)代表這些任務(wù)的 Future 對(duì)象集合
          • shutdown() :在完成已提交的任務(wù)后關(guān)閉服務(wù),不再接受新任務(wù)
          • shutdownNow() :停止所有正在執(zhí)行的任務(wù)并關(guān)閉服務(wù)。
          • isTerminated() :測(cè)試是否所有任務(wù)都執(zhí)行完畢了。
          • isShutdown() :測(cè)試是否該 ExecutorService 已被關(guān)閉

          ScheduledExecutorService 接口

          ExecutorService 的基礎(chǔ)上, ScheduledExecutorService 提供了按時(shí)間安排執(zhí)行任務(wù)的功能,它提供的方法主要有:

          • schedule(task, initDelay): 安排所提交的 Callable Runnable 任務(wù)在 initDelay 指定的時(shí)間后執(zhí)行。
          • scheduleAtFixedRate() :安排所提交的 Runnable 任務(wù)按指定的間隔重復(fù)執(zhí)行
          • scheduleWithFixedDelay() :安排所提交的 Runnable 任務(wù)在每次執(zhí)行完后,等待 delay 所指定的時(shí)間后重復(fù)執(zhí)行。

          代碼: ScheduleExecutorService 的例子

          public class ScheduledExecutorServiceTest {

          ??????? public static void main(String[] args)

          ?????????????? throws InterruptedException, ExecutionException{

          ?????????????? //*1

          ??????????????? ScheduledExecutorService service = Executors.newScheduledThreadPool(2);

          ??????????????? //*2

          ??????????????? Runnable task1 = new Runnable() {

          ???????????????????? public void run() {

          ??????????????????????? System.out.println("Task repeating.");

          ???????????????????? }

          ??????????????? };

          ??????????????? //*3

          ??????????????? final ScheduledFuture future1 =

          ??????????????????????? service.scheduleAtFixedRate(task1, 0, 1, TimeUnit.SECONDS);

          ??????????????? //*4

          ??????????????? ScheduledFuture future2 = service.schedule(new Callable(){

          ???????????????????? public String call(){

          ???????????????????????????? future1.cancel(true);

          ???????????????????????????? return "task cancelled!";

          ??????????????? ?????}

          ??????????????? }, 5, TimeUnit.SECONDS);

          ??????????????? System.out.println(future2.get());

          //*5

          service.shutdown();

          ??????? }

          }

          ?? 這個(gè)例子有兩個(gè)任務(wù),第一個(gè)任務(wù)每隔一秒打印一句“ Task repeating , 第二個(gè)任務(wù)在 5 秒鐘后取消第一個(gè)任務(wù)。

          *1: 初始化一個(gè) ScheduledExecutorService 對(duì)象,這個(gè)對(duì)象的線程池大小為 2

          *2: 用內(nèi)函數(shù)的方式定義了一個(gè) Runnable 任務(wù)。

          *3: 調(diào)用所定義的 ScheduledExecutorService 對(duì)象來(lái)執(zhí)行任務(wù),任務(wù)每秒執(zhí)行一次。能重復(fù)執(zhí)行的任務(wù)一定是 Runnable 類(lèi)型。注意我們可以用 TimeUnit 來(lái)制定時(shí)間單位,這也是 Java 5.0 里新的特征, 5.0 以前的記時(shí)單位是微秒,現(xiàn)在可精確到奈秒。

          *4: 調(diào)用 ScheduledExecutorService 對(duì)象來(lái)執(zhí)行第二個(gè)任務(wù),第二個(gè)任務(wù)所作的就是在 5 秒鐘后取消第一個(gè)任務(wù)。

          *5: 關(guān)閉服務(wù)。

          Executors 類(lèi)

          ?? 雖然以上提到的接口有其實(shí)現(xiàn)的具體類(lèi),但為了方便 Java 5.0 建議使用 Executors 的工具類(lèi)來(lái)得到 Executor 接口的具體對(duì)象,需要注意的是 Executors 是一個(gè)類(lèi),不是 Executor 的復(fù)數(shù)形式。 Executors 提供了以下一些 static 的方法:

          • callable(Runnable task): Runnable 的任務(wù)轉(zhuǎn)化成 Callable 的任務(wù)
          • newSingleThreadExecutor: 產(chǎn)生一個(gè) ExecutorService 對(duì)象,這個(gè)對(duì)象只有一個(gè)線程可用來(lái)執(zhí)行任務(wù),若任務(wù)多于一個(gè),任務(wù)將按先后順序執(zhí)行。
          • newCachedThreadPool(): 產(chǎn)生一個(gè) ExecutorService 對(duì)象,這個(gè)對(duì)象帶有一個(gè)線程池,線程池的大小會(huì)根據(jù)需要調(diào)整,線程執(zhí)行完任務(wù)后返回線程池,供執(zhí)行下一次任務(wù)使用。
          • newFixedThreadPool(int poolSize) :產(chǎn)生一個(gè) ExecutorService 對(duì)象,這個(gè)對(duì)象帶有一個(gè)大小為 poolSize 的線程池,若任務(wù)數(shù)量大于 poolSize ,任務(wù)會(huì)被放在一個(gè) queue 里順序執(zhí)行。
          • newSingleThreadScheduledExecutor :產(chǎn)生一個(gè) ScheduledExecutorService 對(duì)象,這個(gè)對(duì)象的線程池大小為 1 ,若任務(wù)多于一個(gè),任務(wù)將按先后順序執(zhí)行。
          • newScheduledThreadPool(int poolSize): 產(chǎn)生一個(gè) ScheduledExecutorService 對(duì)象,這個(gè)對(duì)象的線程池大小為 poolSize ,若任務(wù)數(shù)量大于 poolSize ,任務(wù)會(huì)在一個(gè) queue 里等待執(zhí)行

          以下是得到和使用 ExecutorService 的例子:

          代碼:如何調(diào)用 Executors 來(lái)獲得各種服務(wù)對(duì)象

          //Single Threaded ExecutorService

          ???? ExecutorService singleThreadeService = Executors.newSingleThreadExecutor();

          //Cached ExecutorService

          ???? ExecutorService cachedService = Executors.newCachedThreadPool();

          //Fixed number of ExecutorService

          ???? ExecutorService fixedService = Executors.newFixedThreadPool(3);

          //Single ScheduledExecutorService

          ???? ScheduledExecutorService singleScheduledService =

          ????????? Executors.newSingleThreadScheduledExecutor();

          //Fixed number of ScheduledExecutorService

          ScheduledExecutorService fixedScheduledService =

          ???? Executors.newScheduledThreadPool(3);

          4LockersCondition接口

          ?? 在多線程編程里面一個(gè)重要的概念是鎖定,如果一個(gè)資源是多個(gè)線程共享的,為了保證數(shù)據(jù)的完整性,在進(jìn)行事務(wù)性操作時(shí)需要將共享資源鎖定,這樣可以保證在做事務(wù)性操作時(shí)只有一個(gè)線程能對(duì)資源進(jìn)行操作,從而保證數(shù)據(jù)的完整性。在 5.0 以前,鎖定的功能是由 Synchronized 關(guān)鍵字來(lái)實(shí)現(xiàn)的,這樣做存在幾個(gè)問(wèn)題:

          • 每次只能對(duì)一個(gè)對(duì)象進(jìn)行鎖定。若需要鎖定多個(gè)對(duì)象,編程就比較麻煩,一不小心就會(huì)出現(xiàn)死鎖現(xiàn)象。
          • 如果線程因拿不到鎖定而進(jìn)入等待狀況,是沒(méi)有辦法將其打斷的

          Java 5.0 里出現(xiàn)兩種鎖的工具可供使用,下圖是這兩個(gè)工具的接口及其實(shí)現(xiàn):

          posted on 2007-03-26 14:30 advincenting 閱讀(473) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           

          公告

          Locations of visitors to this pageBlogJava
        1. 首頁(yè)
        2. 新隨筆
        3. 聯(lián)系
        4. 聚合
        5. 管理
        6. <2007年3月>
          25262728123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          統(tǒng)計(jì)

          常用鏈接

          留言簿(13)

          隨筆分類(lèi)(71)

          隨筆檔案(179)

          文章檔案(13)

          新聞分類(lèi)

          IT人的英語(yǔ)學(xué)習(xí)網(wǎng)站

          JAVA站點(diǎn)

          優(yōu)秀個(gè)人博客鏈接

          官網(wǎng)學(xué)習(xí)站點(diǎn)

          生活工作站點(diǎn)

          最新隨筆

          搜索

          積分與排名

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 东乡族自治县| 伽师县| 灵台县| 德兴市| 宜宾市| 凌源市| 永昌县| 四子王旗| 涿州市| 罗源县| 云霄县| 阳春市| 根河市| 巫溪县| 大化| 桦川县| 白山市| 将乐县| 六安市| 五常市| 时尚| 贵州省| 万盛区| 荆州市| 青阳县| 城市| 安乡县| 上杭县| 玉树县| 邛崃市| 濉溪县| 南木林县| 新密市| 靖边县| 襄汾县| 玉山县| 田阳县| 龙里县| 洪洞县| 蒙阴县| 城固县|