熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

Java5 並發線程學習

2013-11-23 19:45:48  來源: Java高級技術 

  在Java之後並發線程這塊發生了根本的變化最重要的莫過於新的啟動調度管理線程的一大堆API了在Java以後通過Executor來啟動線程比用Thread的start()更好在新特征中可以很容易控制線程的啟動執行和關閉過程還可以很容易使用線程池的特性

  創建任務

  任務就是一個實現了Runnable接口的類

  創建的時候實run方法即可

  執行任務

  通過ncurrentExecutorService接口對象來執行任務該接口對象通過工具類ncurrentExecutors的靜態方法來創建

  Executors此包中所定義的 ExecutorExecutorServiceScheduledExecutorServiceThreadFactory 和 Callable 類的工廠和實用方法

  ExecutorService提供了管理終止的方法以及可為跟蹤一個或多個異步任務執行狀況而生成 Future 的方法 可以關閉 ExecutorService這將導致其停止接受新任務關閉後執行程序將最後終止這時沒有任務在執行也沒有任務在等待執行並且無法提交新任務

  executorServiceexecute(new TestRunnable())

  創建ExecutorService

  通過工具類ncurrentExecutors的靜態方法來創建

  Executors此包中所定義的 ExecutorExecutorServiceScheduledExecutorServiceThreadFactory 和 Callable 類的工廠和實用方法

  比如創建一個ExecutorService的實例ExecutorService實際上是一個線程池的管理工具

  ExecutorService executorService = ExecutorsnewCachedThreadPool()

  ExecutorService executorService = ExecutorsnewFixedThreadPool(

  ExecutorService executorService = ExecutorsnewSingleThreadExecutor()

  將任務添加到線程去執行

  當將一個任務添加到線程池中的時候線程池會為每個任務創建一個線程該線程會在之後的某個時刻自動執行

  關閉執行服務對象

  executorServiceshutdown()

  綜合實例

  
package concurrent;

import ncurrentExecutorService;
import ncurrentExecutors;

/**
* Created by IntelliJ IDEA
*
* @author leizhimin ::
*/
public class TestCachedThreadPool {
        public static void main(String[] args) {
//                ExecutorService executorService = ExecutorsnewCachedThreadPool();
                ExecutorService executorService = ExecutorsnewFixedThreadPool();
//         ExecutorService executorService = ExecutorsnewSingleThreadExecutor();

                for (int i = ; i < ; i++) {
                        executorServiceexecute(new TestRunnable());
                        Systemoutprintln(************* a + i + *************);
                }
                executorServiceshutdown();
        }
}

class TestRunnable implements Runnable {
        public void run() {
                Systemoutprintln(ThreadcurrentThread()getName() + 線程被調用了);
                while (true) {
                        try {
                                Threadsleep();
                                Systemoutprintln(ThreadcurrentThread()getName());
                        } catch (InterruptedException e) {
                                eprintStackTrace();
                        }
                }
        }
}

  運行結果

   ************* a *************
************* a *************
poolthread線程被調用了
************* a *************
poolthread線程被調用了
poolthread線程被調用了
************* a *************
************* a *************
poolthread線程被調用了
poolthread線程被調用了
poolthread
poolthread
poolthread
poolthread
poolthread
poolthread
poolthread
poolthread
poolthread
poolthread
    

  獲取任務的執行的返回值

  在Java之後任務分兩類一類是實現了Runnable接口的類一類是實現了Callable接口的類兩者都可以被ExecutorService執行但是Runnable任務沒有返回值而Callable任務有返回值並且Callable的call()方法只能通過ExecutorService的submit(Callable<T> task) 方法來執行並且返回一個 <T> Future<T>是表示任務等待完成的 Future

  public interface Callable<V>返回結果並且可能拋出異常的任務實現者定義了一個不帶任何參數的叫做 call 的方法

  Callable 接口類似於 Runnable兩者都是為那些其實例可能被另一個線程執行的類設計的但是 Runnable 不會返回結果並且無法拋出經過檢查的異常

  Executors 類包含一些從其他普通形式轉換成 Callable 類的實用方法

  Callable中的call()方法類似Runnable的run()方法就是前者有返回值後者沒有

  當將一個Callable的對象傳遞給ExecutorService的submit方法則該call方法自動在一個線程上執行並且會返回執行結果Future對象

  同樣將Runnable的對象傳遞給ExecutorService的submit方法則該run方法自動在一個線程上執行並且會返回執行結果Future對象但是在該Future對象上調用get方法將返回null

  遺憾的是在Java API文檔中這塊介紹的很糊塗估計是翻譯人員還沒搞清楚的緣故吧或者說是注釋不到位下面看個例子

   import javautilArrayList;
import javautilList;
import ncurrent*;

/**
* Callable接口測試
*
* @author leizhimin ::
*/
public class CallableDemo {
        public static void main(String[] args) {
                ExecutorService executorService = ExecutorsnewCachedThreadPool();
                List<Future<String>> resultList = new ArrayList<Future<String>>();

                //創建個任務並執行
                for (int i = ; i < ; i++) {
                        //使用ExecutorService執行Callable類型的任務並將結果保存在future變量中
                        Future<String> future = executorServicesubmit(new TaskWithResult(i));
                        //將任務執行結果存儲到List中
                        resultListadd(future);
                }

                //遍歷任務的結果
                for (Future<String> fs : resultList) {
                        try {
                                Systemoutprintln(fsget());     //打印各個線程(任務)執行的結果
                        } catch (InterruptedException e) {
                                eprintStackTrace();
                        } catch (ExecutionException e) {
                                eprintStackTrace();
                        } finally {
                                //啟動一次順序關閉執行以前提交的任務但不接受新任務如果已經關閉則調用沒有其他作用
                                executorServiceshutdown();
                        }
                }
        }
}


class TaskWithResult implements Callable<String> {
        private int id;

        public TaskWithResult(int id) {
                thisid = id;
        }

        /**
         * 任務的具體過程一旦任務傳給ExecutorService的submit方法則該方法自動在一個線程上執行
         *
         * @return
         * @throws Exception
         */
        public String call() throws Exception {
                Systemoutprintln(call()方法被自動調用干活!!!             + ThreadcurrentThread()getName());
                //一個模擬耗時的操作
                for (int i = ; i > ; i) ;
                return call()方法被自動調用任務的結果是 + id +      + ThreadcurrentThread()getName();
        }
}

  運行結果

   call()方法被自動調用干活!!!             poolthread
call()方法被自動調用干活!!!             poolthread
call()方法被自動調用干活!!!             poolthread
call()方法被自動調用干活!!!             poolthread
call()方法被自動調用干活!!!             poolthread
call()方法被自動調用干活!!!             poolthread
call()方法被自動調用任務的結果是    poolthread
call()方法被自動調用任務的結果是    poolthread
call()方法被自動調用干活!!!             poolthread
call()方法被自動調用干活!!!             poolthread
call()方法被自動調用干活!!!             poolthread
call()方法被自動調用任務的結果是    poolthread
call()方法被自動調用干活!!!             poolthread
call()方法被自動調用任務的結果是    poolthread
call()方法被自動調用任務的結果是    poolthread
call()方法被自動調用任務的結果是    poolthread
call()方法被自動調用任務的結果是    poolthread
call()方法被自動調用任務的結果是    poolthread
call()方法被自動調用任務的結果是    poolthread
call()方法被自動調用任務的結果是    poolthread

Process finished with exit code


From:http://tw.wingwit.com/Article/program/Java/gj/201311/27417.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.