2

ベクトルには同期されたメソッドが含まれますが、ArrayListsには含まれません。これらの同期されたメソッドは、データが1つ以上のスレッドによってアクセスおよび変更された場合のデータ破損を防ぐのに役立ちます。

誰かが私のためにこれをより詳細に説明できますか?ベクターに同期メソッドが含まれているとはどういう意味ですか?メソッドには、マルチスレッドアクセスのデータのロックとロック解除を制御する内部ロックが含まれていますか?ベクトル(vs. ArrayList)を使用することでデータの破損を防ぎ、問題またはデータ構造と同期の問題にさらに光を当てることができる場所の例を誰かが提供できますか?

お時間を割いていただきありがとうございます。

4

2 に答える 2

3

ベクターに同期メソッドが含まれているとはどういう意味ですか?

メソッドはとしてマークされていsynchronizedます。

メソッドには、マルチスレッドアクセスのデータのロックとロック解除を制御する内部ロックが含まれていますか?

いいえ、キーワードがメソッドにあるにもかかわらず、ロックされているのはメソッドではなくオブジェクトです。メソッド自体をロックする方法はありません。

ベクトル(vs. ArrayList)を使用することでデータの破損を防ぎ、問題またはデータ構造と同期の問題にさらに光を当てることができる場所の例を誰かが提供できますか?

多くの例があります。最も簡単なのは、数値をインクリメントすることです。数を増やす2つのスレッドがあるとします(たとえば、コレクションのサイズ)。同期なしで行うことができます。

Thread1: read size e.g. 0
Thread1: increment size
Thread1: write size e.g. 1
Thread2: read size e.g. 1
Thread2: increment size
Thread2: write size e.g. 2

ただし、スレッドは任意の順序でアクションを実行できるため(これがスレッドの要点であるため)、次のことも可能です。

Thread1: read size e.g. 0
Thread2: read size e.g. 0
Thread1: increment size
Thread2: increment size
Thread1: write size e.g. 1
Thread2: write size e.g. 1

したがって、2つのスレッドがカウンターをインクリメントしたとしても、それらのアクションが調整されていないため、正しくありません。これは、同期が行うことです。

于 2013-01-31T15:56:13.847 に答える
0

はは。8歳の質問。私は答えを探していましたが、オンラインソースから学んで自分でデモを作成しました。私が理解していることは次のとおりです。スレッドセーフにしたいオブジェクトのメソッドでsynchronizedキーワードを使用するか、そのオブジェクトを使用する場所に同期objNameを書き込むことができます。これが誰かを助ける場合の例です。ここで、SyncDataは、同期オブジェクト(データ)を作成したクラスです。

class SyncData {
    synchronized public void print() {
//      public void print() {
        for(int i=1; i<=5; i++) {
            System.out.println("SyncData: print() : "  + Thread.currentThread().getName() + " => " + i);
            try {
                Thread.sleep(1000);
            } catch(InterruptedException excep) {
                System.out.println(excep.getMessage());
            }
        }
    }
}

public class SynchronizedDemo {

    static class SyncChildThread extends Thread {
        SyncData data;
        public SyncChildThread(SyncData data) {
            this.data = data;
        }
        @Override
        public void run() {     
//          synchronized(data) { //alternative way
//              data.print();
//          }
            data.print();
        }
    }

    public static void main(String[] args) {
        //dummy data, which will be shared among multiple threads
        SyncData data = new SyncData();
        SyncChildThread threadOne, threadTwo;
        threadOne = new SyncChildThread(data);
        threadOne.setName("Thread-1");
        threadTwo = new SyncChildThread(data);
        threadTwo.setName("Thread-2");
        threadOne.start();
        threadTwo.start();
    }
}

同期された出力は次のようになります。

SyncData: print() : Thread-1 => 1
SyncData: print() : Thread-1 => 2
SyncData: print() : Thread-1 => 3
SyncData: print() : Thread-1 => 4
SyncData: print() : Thread-1 => 5
SyncData: print() : Thread-2 => 1
SyncData: print() : Thread-2 => 2
SyncData: print() : Thread-2 => 3
SyncData: print() : Thread-2 => 4
SyncData: print() : Thread-2 => 5

同期を削除すると、どのスレッドもいつでもオブジェクトにアクセスできます(同時アクセス)。オブジェクトデータの非同期アクセスの出力:

 AsyncData: print() : Thread-1 => 1
AsyncData: print() : Thread-2 => 1
AsyncData: print() : Thread-1 => 2
AsyncData: print() : Thread-2 => 2
AsyncData: print() : Thread-1 => 3
AsyncData: print() : Thread-2 => 3
AsyncData: print() : Thread-1 => 4
AsyncData: print() : Thread-2 => 4
AsyncData: print() : Thread-1 => 5
AsyncData: print() : Thread-2 => 5
于 2021-07-15T16:21:51.330 に答える