マルチスレッドのシナリオは適切ではありませんでの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操作がロックを加え、全く問い合わせは、複数のスレッドを並列にアクセスすることができるように、存在しません。