Java多線程併發技術

Java多線程併發技術緩存

參考文獻:多線程

http://blog.csdn.net/aboy123/article/details/38307539併發

http://blog.csdn.net/ghsau/article/category/1707779框架

http://www.iteye.com/topic/366591dom

JAVA多線程實現方式主要有三種:繼承Thread類、實現Runnable接口、使用ExecutorService、Callable、Future實現有返回結果的多線程。其中前兩種方式線程執行完後都沒有返回值,只有最後一種是帶返回值的。函數

一、 繼承Thread類實現多線程測試

 

public class MyThread extends Thread {this

  public void run() { //重寫run方法spa

   System.out.println("MyThread.run()");.net

  }

}

 

//調用代碼

MyThread myThread1 = new MyThread();

MyThread myThread2 = new MyThread();

myThread1.start(); // 啓動線程

myThread2.start();

 

Thread本質上也是實現了Runnable接口的一個實例,它表明一個線程的實例,而且,啓動線程的惟一方法就是經過Thread類的start()實例方法

二、 實現Runnable接口方式實現多線程

 

//若是本身的類已經extends另外一個類,就沒法直接extends Thread,此時,必須實現一個Runnable接口,以下:

public class MyThread extends OtherClass implements Runnable {

  public void run() {

   System.out.println("MyThread.run()");

  }

}

 

//爲了啓動MyThread,須要首先實例化一個Thread,並傳入本身的MyThread實例:

MyThread myThread = new MyThread();

Thread thread = new Thread(myThread);

thread.start();

三、 使用ExecutorService、Callable、Future實現有返回結果的多線程

ExecutorService、Callable、Future這個對象實際上都是屬於Executor框架中的功能類。可返回值的任務必須實現Callable接口,相似的,無返回值的任務必須Runnable接口。執行Callable任務後,能夠獲取一個Future的對象,在該對象上調用get就能夠獲取到Callable任務返回的Object了,再結合線程池接口ExecutorService就能夠實現有返回結果的多線程了。

 

  1.      int taskSize = 5;     
  2.    ExecutorService pool = Executors.newFixedThreadPool(taskSize);  // 建立一個線程池  
  3.    // 建立多個有返回值的任務  
  4.    List<Future> list = new ArrayList<Future>();  
  5.    for (int i = 0; i < taskSize; i++) {  
  6.     Callable c = new MyCallable(i + " ");     
  7.     Future f = pool.submit(c);      // 執行任務並獲取Future對象  
  8.     list.add(f);  
  9.    }     
  10.   pool.shutdown();    // 關閉線程池   
  11. for (Future f : list) {  
  12.  // 從Future對象上獲取任務的返回值,並輸出到控制檯  
  13.  System.out.println(">>>" + f.get().toString());   //get()是阻塞調用
  14.  }   

  // 實現Callable接口

  1. class MyCallable implements Callable<Object> {  
  2. private String taskNum;    
  3. MyCallable(String taskNum) {  
  4.    this.taskNum = taskNum;  
  5. }    
  6. public Object call() throws Exception {     
  7.    Thread.sleep(1000);   
  8.    return taskNum + "任務返回運行結果,當前任務時間【" + time + "毫秒】";  
  9. }  

四、 Executors類說明:

參考文獻:http://www.iteye.com/topic/366591

 

Executors類,提供了一系列工廠方法用於建立線程池,返回的線程池都實現了ExecutorService接口。

public static ExecutorService newFixedThreadPool(int nThreads)

建立固定數目線程的線程池。

public static ExecutorService newCachedThreadPool()

建立一個可緩存的線程池,調用execute 將重用之前構造的線程(若是線程可用)。若是現有線程沒有可用的,則建立一個新線程並添加到池中。終止並從緩存中移除那些已有 60 秒鐘未被使用的線程。

public static ExecutorService newSingleThreadExecutor()

建立一個單線程化的Executor。

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

建立一個支持定時及週期性的任務執行的線程池,多數狀況下可用來替代Timer類。

 

ExecutoreService提供了submit()方法,傳遞一個Callable,或Runnable,返回Future。若是Executor後臺線程池尚未完成Callable的計算,這調用返回Future對象的get()方法,會阻塞直到計算完成。

五、 其餘得到線程執行結果的方式:

http://blog.csdn.net/ghsau/article/details/7451464

基於FutureTask

在上述實現中,任務callable被提交後返回一個future用於得到執行結果;

FutureTask實現了兩個接口,Runnable和Future,因此它既能夠做爲Runnable被線程執行,又能夠做爲Future獲得Callable的返回值;

 

  1. public class CallableAndFuture {  
  2.     public static void main(String[] args) {  
  3.         Callable<Integer> callable = new Callable<Integer>() {  
  4.             public Integer call() throws Exception {  
  5.                 return new Random().nextInt(100);  
  6.             }  
  7.         };  
  8.          FutureTask<Integer> future = new FutureTask<Integer>(callable);  
  9.       new Thread(future).start();  
  10.        try {  
  11.           Thread.sleep(5000);// 可能作一些事情  
  12.           System.out.println(future.get());  
  13.      } catch (InterruptedException e) {  
  14.           e.printStackTrace();  
  15.        } catch (ExecutionException e) {  
  16.           e.printStackTrace();  
  17.        }  
  18.    }  

     19.  }  

 

基於CompletionService的實現方式

 

  1.  public class CallableAndFuture {  
  2.     public static void main(String[] args) {  
  3.      ExecutorService threadPool = Executors.newCachedThreadPool();  
  4.         CompletionService<Integer> cs = new ExecutorCompletionService<Integer>(threadPool);  
  5.         for(int i = 1; i < 5; i++) {  
  6.             final int taskID = i;  
  7.             cs.submit(new Callable<Integer>() {  
  8.                 public Integer call() throws Exception {  
  9.                     return taskID;  
  10.              }  
  11.            });  
  12.          }  
  13.          // 可能作一些事情  
  14.          for(int i = 1; i < 5; i++) {  
  15.              try {  

        //take 每次得到一個執行完成的future,若是沒有就阻塞,與其功能相同的非阻塞調用時poll

  1.                 System.out.println(cs.take().get());  
  2.            } catch (InterruptedException e) {  
  3.                  e.printStackTrace();  
  4.             } catch (ExecutionException e) {  
  5.                 e.printStackTrace();  
  6.              }  
  7.          }  
  8.       }  

       }  

 

六、 多線程相關函數:

參考文獻:http://blog.csdn.net/ghsau/article/details/17560467

 

線程中斷:http://blog.csdn.net/z69183787/article/details/25076033

void

interrupt()  //    中斷線程。其實只是設置了中斷標誌位

static boolean

interrupted() //  測試調用該方法的當前線程是否已經中斷。同時清除中斷標誌位

boolean

isInterrupted() // 測試this線程是否已經中斷。不清除中斷標誌位

線程讓步

static void

yield() //     暫停當前正在執行的線程對象,並執行其餘線程

注意: 若是存在synchronized線程同步的話,線程讓步不會釋放鎖(監視器對象)

線程休眠:

static void

sleep(long millis)//  在指定的毫秒數內讓當前正在執行的線程休眠(暫停執行)。

注意: 若是存在synchronized線程同步的話,線程休眠不會釋放鎖(監視器對象),但會釋放cpu

 

線程合併:http://uule.iteye.com/blog/1101994

 void

join()          等待該線程終止。

 void

join(long millis)          等待該線程終止的時間最長爲 millis 毫秒。

 void

join(long millis, int nanos) 等待該線程終止的時間最長爲 millis 毫秒 + nanos 納秒。

線程合併是優先執行調用該方法的線程,再執行當前線程。內部是用wait方法實現的

 

  1. public class JoinTest {  
  2.     public static void main(String[] args) throws InterruptedException {  
  3.         JoinThread t1 = new JoinThread("t1");  
  4.         JoinThread t2 = new JoinThread("t2");  
  5.         t1.start();   //啓動線程
  6.         t2.start();  //啓動線程
  7.         t1.join();   //等待該線程執行完畢
  8.         t2.join();  //
  9.         System.out.println("主線程開始執行!");  
  10.    }  

11. }  

      class JoinThread extends Thread {  

  1.      public JoinThread(String name) {  
  2.        super(name);  
  3.        }  
  4.       public void run() {  
  5.        for(int i = 1; i <= 10; i++)  
  6.             System.out.println(getName() + getId() + "執行了" + i + "次");  
  7.      }  

    } 

 

七、 線程同步之鎖

 鏈接:http://blog.csdn.net/ghsau/article/details/7461369

相關文章
相關標籤/搜索