ベクトル、ソースコードの解析とCopyOnWriteArrayListと

マルチスレッドのシナリオは適切ではありませんでのArrayListとLinkedListのは、以前、説明しました。JDKは、スレッドセーフリストを提供します。

ベクターは、スレッドセーフとCopyOnWriteArrayListとあります

1、ベクトル

ArrayListを持つクラスのプロパティとメソッド、主な違いは、スレッドセーフな目的を達成するように、その主な方法は、同期キーワードと組み合わされる上ベクトルです。

 

2、CopyOnWriteArrayListとソースコード解析

パブリッククラスCopyOnWriteArrayListと<E> 
    用具一覧<E>、ランダム・、Cloneableを、java.io.Serializableの{ 
    最終過渡ReentrantLockのロック=新しいReentrantLockの()。

    //使用数组存储数据
    プライベート過渡揮発性のオブジェクト[]配列。
}

 ArrayListの、マルチスレッドセーフ、より少ないカウントサイズのロックに関して 

 

3、CopyOnWriteArrayListとコンストラクタ

    // 1、空构造函数
    パブリックCopyOnWriteArrayListと(){ 
        はsetArray(新しいオブジェクト[0])。
    } 

    // 2、集合构造函数
    公共CopyOnWriteArrayListと{(コレクションは、c <E延び?>)
        オブジェクトの[]の要素を、
        IF(c.getClass()== CopyOnWriteArrayList.class)
            要素=(<?>(CopyOnWriteArrayListと)C).getArray(); 
        他{ 
            要素= c.toArray()。
            // c.toArrayは(間違って)(6260652を参照してください)] [オブジェクトを返さない可能性があります
            場合は(elements.getClass()!=オブジェクト[]。クラス)
                の要素= Arrays.copyOf(要素、elements.length、オブジェクト[]。クラスを); 
        } 
	//赋值给当前配列
        はsetArray(要素) 
    } 

    //。3、デジタルコンストラクタ
    公共CopyOnWriteArrayListと(E [] toCopyIn){ 
        はsetArray(Arrays.copyOf(toCopyIn、toCopyIn.length、オブジェクト[]クラス)。)。
    } 
    //はsetArray方法
    最終ボイドはsetArray(オブジェクト[] A){ 
        アレイ=。
    }

  主引数がデジタルオブジェクトに解析され、そして次にアレイにコピーされ

 

 

4、add操作

    // 1、単一要素追加
    追加ブール公開(E E){     
    } 
    // 2は、位置に単一の要素を追加
    {追加(INTインデックス、E要素)を無効公共
       
    } 
    要素のコレクションを追加して、//。3 
    (パブリックブールのaddAllコレクション<?延びE> C){ 
    } 

    // 4、追加するセット位置から
    パブリックブールのaddAllを(int型のインデックス、コレクションは C <?E延び>)を{
    

  主な公共ブールアドオンの分析(E電子)

    パブリックブール追加(E、E){ 
        最終ReentrantLockのロック= this.lock。
 	// 1、获取锁对象
        lock.lock()。
        {試みる
	    增加元素、2 // 
            オブジェクト[] =要素のgetArray()。
            int型のlen = elements.length。
            オブジェクト[] =たnewElements Arrays.copyOf(要素、LEN + 1)。
            たnewElements [LEN] = E。
            setArray(たnewElements)。
            trueを返します。
        }最後に{ 
	    // 3、释放锁
            lock.unlock()。
        } 
    }

  なお、自動拡張のCopyOnWriteArrayListとはないのArrayList(1.5)、操作Arrays.copyOf実行を追加し、これがパフォーマンスのボトルネックになります

 

5、削除

私たちは、主に見えます

    パブリックE削除(INTインデックス){ 
        最終ReentrantLockのロック= this.lock。
	// 1、获取锁
        lock.lock()。
        {試みる
            オブジェクト[] =要素のgetArrayを(); 
            int型のlen = elements.length。
            E OLDVALUE = GET(要素、インデックス); 
            int型numMoved = LEN -インデックス- 1。
            (numMoved == 0)場合
                はsetArray(Arrays.copyOf(要素においてlen - 1))。
            他{ 
                [たlen - 1]オブジェクト[]れたnewElements =新しいオブジェクト。
                System.arraycopyの(要素、0たnewElements、0、インデックス)。
                System.arraycopyの(要素、指数+ 1たnewElements、インデックス
                                 numMoved); 
                setArray(たnewElements)。
            }
            OLDVALUEを返します。
        }最後に{ 
            lock.unlock()。
        } 
    }

  

6、変更操作

私たちは、見て

    パブリックEセット(INTインデックス、E要素){ 
        最終ReentrantLockのロック= this.lock。
        lock.lock(); 
        {試みる
            オブジェクト[] =要素のgetArrayを(); 
            E OLDVALUE = GET(要素、インデックス); 

            もし(OLDVALUE =要素!){ 
		//直接获取元素、并替换
                int型のlen = elements.length。
                オブジェクト[] =たnewElements Arrays.copyOf(要素、LEN)。
                たnewElements [インデックス] =要素; 
                setArray(たnewElements)。
            {}他
                //未かなり無操作; 揮発書き込みセマンティクスを保証
                はsetArray(要素)。
            } 
            OLDVALUEを返します。 
        }最後に{ 
            lock.unlock()。
        } 
    }

  

7、クエリ操作

    プライベートEのGET(オブジェクト[] A、INTインデックス){ 
        リターン(E)[インデックス]。
    } 

    パブリックEのGET(INTインデックス){ 
        リターンGET(のgetArray()、指数); 
    }

  スレッドセーフではありません、ここで取得します。

そして、ベクトルのクエリ操作、同期の変更は、スレッドセーフです。

    公共同期Eのget(int型のインデックス){ 
        場合(インデックス> =し、elementCount)
            新しいArrayIndexOutOfBoundsExceptionが(インデックス)を投げます。

        リターンからelementData(インデックス); 
    }

  概要:のベクトルにかかわらず、追加および削除の操作、または照会操作は、すべての同期ロックで結合され、

CopyOnWriteArrayListとでは、唯一のCRUD操作がロックを加え、全く問い合わせは、複数のスレッドを並列にアクセスすることができるように、存在しません。

 

おすすめ

転載: www.cnblogs.com/linlf03/p/12633792.html