1. 程式人生 > >JAVA基礎複習(七)多執行緒和網路

JAVA基礎複習(七)多執行緒和網路

1、建立執行緒和任務,如:

//任務類必須實現Runnable介面
public class TaskClass implements Runnable{
 ...
      public TaskClass(...){
      ...
      }
      //想要在該執行緒執行的任務
      public void run(){
      ...
      }
...
}
//呼叫,run方法會被自動呼叫,無需特意呼叫它
...
public void someMethod(){

      TaskClass task1=new TaskClass(...);
      TaskClass task2=new TaskClass(...);

      Thread thread1=new Thread(tasks);
      Thread thread2=new Thread(tasks);

      thread1.start();
      thread2.start();
}
...

2、因為Thread類實現了Runnable,所以可以定義一個Thread的拓展類,並且實現run方法,但是不推薦這種方法,它將任務和執行任務的機制混在了一起,將任務從執行緒中分離出來是比較好的設定。

3、Thread類包含為任務而建立的執行緒的構造方法以及控制執行緒的方法,start()啟動執行緒使方法run()被呼叫、isAlive測試執行緒當前是否正在執行、setPriority()設定執行緒的優先順序0~10、join()等待執行緒結束、sleep()指定執行緒睡眠數,有一個必檢異常、yield()使執行緒暫停並執行執行其他執行緒、interrupt()中斷執行緒。

4、執行緒池是管理併發執行任務個數的理想方法,提供了Executor介面來

執行執行緒池中的任務,提供ExecutorService介面來管理和控制任務。如:

import java.util.concurrent.*;

public class ExecutorDemo{
  //線上程池中建立3個執行緒,如果改成1,三個任務將順序執行,如果預設不填則所有任務都併發地執行
  ExecutorService executor=Executors.newFixedThreadPool(3);

  //執行任務
  executor.execute(task1);
  executor.execute(task2);
  executor.execute(task3);

  //關閉執行緒池,但所有任務都將繼續執行直至完成
  executor.shutdown();
}

5、如果一個共享資源被多個執行緒同時訪問,可能會遭到破壞,即競爭狀態,執行緒不安全。為了避免競爭狀態,應該防止多個執行緒同時進入某一特定部分,程式中的這部分被稱為臨界區。呼叫一個物件的同步例項方法要求給該物件加鎖,呼叫一個類的同步靜態方法要求對該類加鎖。當執行一個方法中某一個程式碼塊時,同步語句不僅可用於對this物件加鎖,而且可用於對任何物件加鎖。這個程式碼塊稱為同步程式碼塊synchronized(隱式加鎖),而一個鎖是Lock介面的例項,它定義了加鎖和釋放鎖的方法(顯示加鎖【lock()、unlock()、newCondition()返回繫結到Lock例項的新的Condition例項】,ReentrantLock是為建立相互排斥的鎖Lock的具體實現,可以建立具有特定的公平策略的鎖,真正公平的策略確保等待最長的執行緒首先獲得鎖):

//任何同步例項方法都可以轉化為同步語句
synchronizied(expr){
   statements;
}
public synchronized void someMethod(...){

}
//任務執行類
public static class Tasking implements Runnable{
      //執行緒裡執行的操作
      public void run(){
             TaskClass task=new TaskClass();
             task.someMethod(...);
      }

}
//加鎖操作類
public static class TaskClass(){

privite static Lock lock=new ReentrantLock();//建立一個鎖

public void someMethod(...){
      lock.lock();//加鎖
      try{
      //執行操作
      ...
     }catch(InterruptedException ex){

     }finally{
     lock.unlock();//釋放鎖
  }
 }

}

6、通過保證在臨界區上多個執行緒的相互排斥,執行緒同步完全可以避免競爭狀態的發生,但是有時候還需要執行緒之間的相互協作。一個執行緒可以指定在某種條件下該做什麼,條件是通過呼叫Lock物件的newCodition()方法而建立的物件,一旦建立了條件,就可以使用(await()可以讓當前執行緒都出於等待狀態,直到條件發生、signal()喚醒一個等待的執行緒、signalAll()方法喚醒所有等待的執行緒)來實現執行緒之間的相互通訊。

7、監視器是一個相互排斥且具備同步能力的物件,監視器中的一個時間點,只能有一個執行緒執行方法。任意物件都可能是一個監視器,一旦一個執行緒鎖住物件,該物件就成為監視器。其中(這三個方法類似第六點上的三個方法)wait()、notify()和notifyAll()方法必須在這些方法的接收物件的同步方法或同步程式碼塊中呼叫

8、訊號量可以用來限制訪問共享資源的執行緒數,為了建立訊號量,必須使用可選擇的公平策略來確定許可的數量,Semaphore類攜帶兩個構造方法,和acquire()獲取這個訊號量的許可、release()釋放一個許可給該訊號量。【只有一個許可的訊號量可以用來模擬一個互斥的鎖】

9、有時兩個或多個執行緒需要在幾個共享物件上獲取鎖,這可能會導致死鎖,使用一種名為資源排序的簡單技術可以輕易避免死鎖的發生,該技術是給一個需要鎖的物件指定一個順序,確保每個執行緒都按這個順序來獲取鎖。

10、執行緒的狀態:新建、就緒、執行、阻塞或結束

11、可以通過鎖定集合或者同步集合保護集合的資料,Collections類提供了六個靜態方法將集合轉換成同步版本【synchronizedCollection、synchronizedList、synchronizedMap、synchronizedSet、synchronizedSortedMap、synchronizedSortedSet】,這些同步類包裝都是執行緒安全的,但是迭代器具有快速失敗的特性需要建立一個集合物件,並且在遍歷它時獲取物件上的鎖

Set hashSet=Collections.synchronizedSet(new HashSet());

synchronized(hashSet){
    Iterator iterator=hashSet.iterator();
    
    while(iterator.hasNext()){
          System.out.println(iterator.next());
   }
}

12、網路在為小程式進行前後臺互動時使用較多,和諸多字串、Json、位元組流以及網路工具包配合使用

13、基於流的通訊使用傳輸控制協議TCP【無損可靠】進行資料傳輸,基於包的通訊使用使用者資料報協議UDP