-1

これは何度も聞かれる質問ですが、Java の初心者 (私のようなもの) は、与えられた答えを深く理解できるとは限りません。

私はJavaの本を何冊か読んでいますが、そのうちの1つで、VectorとArrayListの違いは、前者が同期され、後者が同期されていないことです(StringBufferとStringBuilderと同じです)。

そして、この本は、「必要に応じて、同期されていないコードに同期を「追加」できる」と説明しています。

この投稿で Brian Roach は、「StringBuffer と Vector にはスレッド同期があり、オーバーヘッドが追加されます (必要でない限り、ただし、それを新しいクラスに追加する方法はあります) 」 と説明しています。

だから、私は3つの質問があります:

1) 同期によってオーバーヘッドが増えるが、必要に応じて新しいクラスに追加できる場合、StringBuilder と ArrayList に同期を追加する代わりに、StringBuffer と Vector を使用しないのはなぜですか?

2) クラスに同期を追加するにはどうすればよいですか?

3) 同期の目的は何ですか?

初心者の質問で申し訳ありませんが (もっと本を読まなければならないことはわかっています)、これらの概念を理解するのは簡単ではありません。

4

4 に答える 4

4

同期にはそれに関連するオーバーヘッドがあり、パフォーマンスが不必要に低下する可能性があります。次のコード スニペットを検討してください。

synchronized(this) {
   doSomething();
}

スレッドが同期ブロックに入るたびに、ロックを取得する必要があります。ブロックを離れると、ロックを放棄します。これにより、複数のスレッドが同時にコード ブロックに入るのを防ぐことができます。

コードを同期する必要がない場合 (一度に 1 つのスレッドのみがアクセスするため)、次のようにコードを記述できます。

doSomething();

要約すると、オーバーヘッドが追加されるため、必要でない限り、通常は同期バージョンを使用しないでください。ただし、同期ブロック (および/またはロック) を使用していつでも同期を追加できます。

于 2012-12-29T17:26:15.057 に答える
0

1) 同期によってオーバーヘッドが増えるが、必要に応じて新しいクラスに追加できる場合、StringBuilder と ArrayList に同期を追加する代わりに、StringBuffer と Vector を使用しないのはなぜですか?

私見、同期された StringBuffer を持つ正当な理由はありませんでした。他のコレクションとの一貫性のために行われただけだと思います。これを使用する唯一の理由は、それを主張する API がある場合です。

Vector はより便利で、 Collection.synchronizedList() を使用できますが、一部の API ではそれが必要です。Java 5.0 以降、一部の同時実行コレクションがより適切な選択になりました。

2) クラスに同期を追加するにはどうすればよいですか?

すべてのメソッドにキーワードを追加しsynchronizedます (他にもありますが、最も単純なケースではそれだけで十分です) SynchronizedList のような同期ラップを作成することもできます

3) 同期の目的は何ですか?

スレッドセーフ。

于 2012-12-29T22:56:21.017 に答える
0

1)Vector以前に Java API に導入されたためArrayList。もう使用する正当な理由はほとんどありVectorません。StringBuffervsも同様です。StringBuilder

2)同期が必要な場合は、インスタンスがアクセス/変更されるメソッド(またはブロック)を同期できます

于 2012-12-29T17:24:38.350 に答える
0

互換性。彼らは既存のクラスを変更したくありませんでした。そのため、自動的に同期されないバリアントを追加しました。同期リストにArrayListラップすることで同期を作成できます。List<String> list = Collections.synchronizedList(new ArrayList<String>());

同期についてはウィキペディアで説明されています。そこから読み始めます。

シンプルな同期 ArrayList の例:

 // Class definition
 ArrayList<String> foo;

 void doSomething() {
     synchronized(foo) {
         foo.add("Foobar");
     }
 }

メソッドdoSomethingはスレッドセーフです。

于 2012-12-29T17:27:07.400 に答える