4

私が以下のようなものを持っている場合、それは内部で何を意味しますかsynchronized block

synchronised (syncObject) {

基本的に、上記のブロック内に含めることができるスレッドは1つだけであり、1つのスレッドの実行が終了するとすぐに、2番目のスレッドがその同期ブロックsynced(syncObject)に入ります。右?私がより良い写真を撮れるように、誰かがLayMan言語で私に説明できますか?

private static final class Task implements Runnable {
{
  private static Object syncObject = new Object();

    public Task(Command command, BlockingQueue<Integer> pool1, BlockingQueue<Integer> pool2) {
    this.command = command;
    this.existPool = pool1;
    this.newPool = pool2;
}

  public void run()
  {
    synchronised (syncObject) {
      if() {
        existId = existPool.take();
        attributeMethod(existId);
        } else if() {
            newId = newPool.take();
            attributeMethod(newId);
        }
    }
  }
}

// So I need to make this method synchronized or not? Currently I have made this synchronized
private synchronized void attributeMethod(int range) {
    // And suppose If I am calling any other method here-

 sampleMethod();
}


// What about this method, I need to make this synchronized as well? or not?
private synchronized void sampleMethod() {


}
4

2 に答える 2

10

基本的に、上記のブロック内に含めることができるスレッドは1つだけであり、1つのスレッドの実行が終了するとすぐに、2番目のスレッドが同期された同期ブロック(syncObject)に入ります。右?

右!

したがって、このメソッドを同期させる必要がありますか?

いいえ、しません。メソッドがメソッド内の同期されたブロック内からのみ呼び出されると仮定するとrun()、そのブロックはすでに複数のスレッドがメソッドを同時に実行することを防ぎます。したがって、メソッドを宣言することsynchronizedは冗長です。

ただし、いくつか指摘する必要があります。

  • インスタンスメソッドをとして宣言すると、 ;synchronizedで同期されます。thisつまり、Taskオブジェクト上。しかし、あなたのsynchronizedブロックは別のオブジェクトで同期しています...のオブジェクトsyncObject。この場合、これは問題ではありません。ただし、メソッドsynchronized内のブロックrun()が存在しない場合は、スレッドが異なるオブジェクトで同期を試みていることがわかります...そして相互排除は行われません。

  • メソッドのトップレベルで同期することにより...そのタスクを実行するすべてのスレッドにrun()単一の共有syncObjectを使用します...タスクを一度に1つずつ効果的に実行します。これにより、スレッドを使用するメリットが完全に失われます。

  • プライベートロックオブジェクト(などsyncObject)を含む変数をであると宣言することをお勧めしますfinal。これにより、何かが上書きして同期が失敗する可能性を回避できます。

于 2012-08-21T01:28:23.013 に答える
1

いいえ、すでにブロックattributeMethodのスコープ内で実行されています。synchronizedこのブロックの外で同時に呼び出す場合を除いて、そのようにマークする必要はありません。

于 2012-08-21T01:09:23.847 に答える