マルチスレッド高同時性

7576 ワード

マルチスレッド高同時性
ワイヤロック
Lock synchronized
  • synchronizedはjavaに内蔵された言語で、javaのキーワード
  • です.
  • synchronizedは、synchronizedメソッドまたはsynchronizedコードブロックが実行されると、手動でロックを解除する必要はありません.ロックの使用量は自動的に解放されます.ロックは手動でロックを解除する必要があります.アクティブなロックがない場合、デッドロックの問題が発生する可能性があります.
  • ReentrantLockは2つの構造関数を再ロックすることができる.フェアロックと非フェアロック
  • ReentrantReadWriteLock読み書きロック
  • 書き込み時には他のスレッドはデータの読み取りや書き込みができないが、読み出し時には他のスレッドはデータの書き込みができないが、データの読み取り(同時読み取り可能)
  • が可能である.
    ReadWriteLock lock = w new ReentrantReadWriteLock();
    lock.writeLock().unlock();
    //  unlock()  lock     ,          ,        ,             
    lock.readLock().lock();
    
    ReentrantReadWriteLock              :
       :                   
    readWriteLock.writeLock().lock();
    readWriteLock.readLock().lock();
    readWriteLock.writeLock().unlock();
       :                      
    ReentrantReadWriteLock       
    

    スレッドプール
    Executors
  • SingleThreadExecutor 1スレッドのみのスレッドプール
  • newCachedThreadPoolは、必要に応じて新しいスレッドのスレッドプールを作成できます.
  • スレッドプールには多くのスレッドが同時に実行する必要があり、古い使用可能なスレッドは新しいタスクによって再実行され、スレッドが60秒を超えると実行されず、終了し、プールから
  • 削除されます.
  • スレッドプールは無限大であり、2番目のタスクを実行するたびに最初のタスクが完了すると、新しいスレッドを作成するのではなく、最初のタスクを実行するスレッドが多重化されます.ただし、リサイクル可能なスレッドがない場合は、新しいスレッドが作成されます.同時量を特別にするとOOM
  • になります
  • newFixedThreadPool固定スレッドプール
  • Scheduled Thread l Poolスケジューリング可能スレッドプール定長スレッドプールを作成し、タイミングおよび周期的タスク実行をサポート
  • scheduleAtFixedRate
  • scheduledThreadPool.schedule(new Runnable() {}, 3,TimeUnit.SECONDS);
  • scheduledThreadPool.scheduleAtFixedRate(new Runnable(),1,3,TimeUnit.SECONDS)
  • 1遅延実行3実行期間
  • runメソッド内で実行がタイムアウトした場合、タイムアウト時間で
  • を実行する.
  • scheduleWithFixedDelay
  • scheduledThreadPool.scheduleWithFixedDelay(new Runnable(),1,3,TimeUnit.SECONDS)
  • runメソッド内の実行がタイムアウトする場合、
  • は所定の時間に実行される.

  • Single Thread Scheduled Poolスケジューリング可能な単一スレッドのスレッドプール
  • メッセージキューをビルドする
      Java               ,          ,           ,                       。              ?
    
                   ,                      ,          ,        ,                 ,        ,              。                            。            ,                          
    
         :ConcurrentLinkedQueue
        :ArrayBlockingQueue、LinkedBlockingQueue、……
    

    市場の多くのニュースキューの原型はJDK 1.5以降の共同発注を参考にしており、最も核心的なのはBlockingQueueである.BlockingQueueはjava.util.concurrentの下で主にスレッドの同期を制御するためのツールです
      :
    1)add(anObject):  anObject    BlockingQueue  ,    BlockingQueue     ,    true,      
    2)offer(anObject):        , anObject   BlockingQueue ,    BlockingQueue    ,    true,     false.
    3)put(anObject):  anObject    BlockingQueue  ,   BlockQueue     ,              BlockingQueue  
    
      :
    4)poll(time):   BlockingQueue         ,       ,     time        ,       null
    5)take():   BlockingQueue         ,  BlockingQueue   ,           Blocking           
    
  • ArrayBlockingQueue
  • 配列のブロックキューに基づいて、ArrayBlockingQueueには、オブジェクト
  • をキャッシュするための一定長配列が維持されている.
  • ArrayBlockingQueueの生産者と消費者は同じロック
  • を使用しています.
  • 生産者がデータを挿入するキューの最後に、消費者は常にキューの頭からデータを取り、キューがいっぱいになった後、キューにデータを挿入するとキューのブロックをもたらし、同様に、空のキューからデータを取り、ブロックの
  • である.
  • キュー内のデータが常に生産者の生産データの順序に従ってキュー内のデータを取得することを望むならば、構造関数でfairパラメータをtrueに設定すればよいが、この操作はスループット
  • を低下させる.
  • LinkedBlockingQueue
  • チェーンテーブルに基づくブロックキューは、実際には内部でもデータを維持するバッファキューであるが、このキューはチェーンテーブルからなる
  • である.
  • は、LinkedBlockingqueueが生産側と消費側に対して異なるロック(すなわち、読み書きロックは互いに独立している)を設計しているため、高い同時シーンでは、linkedBlockingQueueがArrayBlockingQueue
  • よりも優れているため、同時性においてより効率的である.
    ArrayBlockingQueueは境界があり、キューのサイズを指定する必要があります.LinkedBlockingQueueは無境界であり、キューのサイズを指定しなくてもよいが、デフォルトはInteger.MAX_VALUE.もちろん、キューサイズを指定して境界を持つこともできます.ArrayBlockingQueueのロックは分離されていません.すなわち、生産と消費用は同じロックです.LinkedBlockingQueueのロックは分離されています.すなわち、生産用はputLockで、消費はtakeLock です.
  • DelayQueue
  • DelayQueueは、遅延期間が満了した場合にのみ要素
  • を抽出できる無境界ブロックキューです.
  • クライアントが長時間接続を占有する問題は、この空き時間を超えて、長時間使用しないキャッシュを除去することができる.キュー内のオブジェクトが長時間使用されず、空き時間を超えると、タスクタイムアウト処理
  • が削除される.
  • DelayQueueは、PriorityQueue(PriorityQueue)を使用して実現されるBlockingQueueであり、優先キューの比較基準値は時間である.この2つの関数を実装することによって比較
  • を実現する.
  • PriorityBlockingQueue
  • 優先度に基づくブロックキュー(優先度の判断はコンストラクション関数によって伝達されるオブジェクト、このオブジェクトの中で実現されるcompareToメソッドによって決定される)は、ArrayBlockingQueueと非常に類似しており、生産と消費では共通のロックが使用されているが、異なるのは、指定された長さの有無にかかわらず、自動拡張
  • が実現できることである.
  • SynchronousQueue
  • concurrentLinkedQueue

  • コンカレントクラスコンテナ
  • java.util.concurrentには複数の同時コンテナが用意されています
  • キューQueueタイプのBlockingQueueとConcurrentLinkedQueue
  • MapタイプのConcurrentMap
  • SetタイプのConcurrentSkipListSetとCopyOnWriteArraySet
  • ListタイプのCopyOnWriteArrayList
  • CopyOnWriteコンテナ
  • CopyOnWriteArrayList
  • CopyOnWriteArraySet
  • CopyOnWrite           。                     ,          ,           Copy,         ,           ,       ,              。             CopyOnWrite         ,      ,              。   CopyOnWrite              ,        。
         ,CopyOnWriteArrayList       :      ,   ,                      
    CopyOnWrite               ,            。             ,     ,      CopyOnWrite   
    
  • ConcurrentMapコンテナ
  • ConcurreentHashMap
  • ConcurrentSkipListMap
  • HashMap     
            ,   HashMap    put         ,   CPU       100%,             HashMap
    HashTable    
    HashTable      synchronized        ,             HashTable        。
    
    ConcurrentHashMap 16 segment 
    ConcurrentHashMap           ,          Segment   ,  Segment       HashTable   ,Segment            
            segment   segment    
    
    concurrentSkipListMap   JDK1.6          ,    ;           ;               concurrentSkipListMap    ,        ,              
    concurrentSkipListMap   TreeMap   ,             ,   ,         
    

    CPU cache
    CPUの周波数が向上するにつれて、メモリのアクセス速度は質的な突破がなく、アクセスメモリの速度が遅いことを補うために、CPUの計算資源を十分に発揮し、CPU全体のスループットを高めるために、CPUとメモリの間に1級Cacheを導入した.ホットスポットデータの体積がますます大きくなるにつれて、一級Cache L 1はすでに発展の要求を満たさず、二級Cache L 2、三級Cache L 3を導入した.
    レベルが小さいほどCPUに近いため、速度も速く、容量も小さいことを意味します.
    キャッシュ行
  • キャッシュは、キャッシュ行から構成されます.一般的に1行のキャッシュ行は64バイトです.したがって、キャッシュを使用する場合は、1バイトではなく、1行のキャッシュ行、1行のキャッシュ行が使用されます.すなわち,CPUアクセスキャッシュはいずれも1行ずつ最小単位で動作する.
  • 64ビットシステムでは、Java配列オブジェクトヘッダは固定16バイトであり、longタイプは8バイトである.したがって、16+8*6=64バイトは、1つのキャッシュ行の長さ(1つのキャッシュ行に6つのlongタイプのデータを埋め込むことができる)
  • に等しい.
  • 擬似共有
  • 擬似共有の非標準定義は、キャッシュシステムにおいてキャッシュライン(cache line)単位で格納され、マルチスレッドが互いに独立した変数を変更すると、これらの変数が同じキャッシュラインを共有すると、互いの性能に無意識に影響を及ぼす、擬似共有である.
  • Javaクラスでは、最適化された設計は、どの変数が変わらないのか、どの変数が常に変化しているのか、どの変化が完全に独立しているのか、どの属性が一緒に変化しているのか、宣言時に同じキャッシュライン
  • に配置されるのかを明確にすることである.
    public class DataPadding{
    	long a1,a2,a3,a4,a5,a6,a7,a8; //             
    	int value;
    	long modifyTime;
    	long b1,b2,b3,b4,b5,b6,b7,b8; //          ;
    	boolean flag;
    	long c1,c2,c3,c4,c5,c6,c7,c8; //
    	long createTime;
    	char key;
    	long d1,d2,d3,d4,d5,d6,d7,d8; //             
    }
    
    //                      cache line  
    @sun.misc.Contended
    @SuppressWarnings("restriction")
    	public class ContendedData {
    	int value;
    	long modifyTime;
    	boolean flag;
    	long createTime;
    	char key;
    }
    //    :
    //              
    @SuppressWarnings("restriction")
    public class ContendedGroupData {
    	@sun.misc.Contended("group1")
    	int value;
    	@sun.misc.Contended("group1")
    	long modifyTime;
    	@sun.misc.Contended("group2")
    	boolean flag;
    	@sun.misc.Contended("group3")
    	long createTime;
    	@sun.misc.Contended("group3")
    	char key;
    }