私は同期ブロックを理解するための助けが必要です。以下の例を仮定:Javaスレッド:synchronizedブロック
public class ThreadStarter {
public static void main(String[] args) {
Queue queueObject = new Queue();
ThreadA thread1 = new ThreadA(queueObject);
ThreadA thread2 = new ThreadA(queueObject);
ThreadB thread3 = new ThreadB(queueObject);
ThreadB thread4 = new ThreadB(queueObject);
thread1.start();
thread2.start();
}
}
public class Queue {
Object[] the theQueue;
public Queue(int size){
theQueue = new Object[size];
}
public submitObject(Object o){
/* add Object to the queue */
}
public deleteObject(int objectId){
/*delete Object from the queue */
}
}
public class ThreadA extends Thread {
private Queue queue;
public ThreadA(Queue queue){
this.queue = queue;
}
public void run() {
while(!isInterrupted()){
synchronized(queue) {
Object o = new Object
queue.submitObject(o);
/* do some other stuff */
}
try {
sleep((int)(Math.random()*1000));
} catch (interruptedException) {
Thread.currentThread().interrupt;
}
synchronized(queue) {
/* do some other stuff on the queue */
}
}
}
}
public class ThreadB extends Thread {
private Queue queue;
public ThreadB(Queue queue){
this.queue = queue;
}
public void run() {
while(!isInterrupted()){
synchronized(queue) {
queue.deleteObject(o);
/* do some other stuff */
}
try {
sleep(1000);
} catch (interruptedException) {
Thread.currentThread().interrupt;
}
}
}
}
私の質問があり、それは十分に安全側であることを、キュークラスにオブジェクトを提出するスレッドAで全体キューオブジェクトを同期させることですか? ThreadBで同じことをして、キューからオブジェクトを削除しました。または、QueueクラスのsubmitObject()メソッドとdeleteObject()メソッドを同期させる必要がありますか?
私の理解では、上記のようにスレッドのクラス全体をロックすると、私は安全な側にいるはずです。
greetZと事前に感謝します。
+1:同期をカプセル化するほど、より簡単で安全です。 –
機能的には、 'queue'のメソッドを同期させることと同等ではありません。彼がそれをした場合、各 'synchronized 'セクションにある'/* do some other stuff */'はクリティカルセクションにはなく、並行して実行できます。そのコードの内容によっては、同期することも重要です。これは同期されたリストに似ています。複数の操作をアトミックに(たとえば反復処理を)実行する場合は、リスト上で外部的に同期する必要があります。 –
@MaxPeters完全に同意します。 – assylias