マルチスレッド-Synchronizedを使用して注意すべき問題


1.Monitorに関連付けられているオブジェクトは空にできません


つまり、Synchronized()カッコ内のオブジェクトはnullではありません.
private final Object obj = null;
public void syncMethod(){
    Synchronized(obj){
    }
}

2.synchronizedの役割ドメインが大きすぎる


synchronizedには排他性があるため、synchronizedの役割ドメインが大きすぎると、効率が非常に低く、合併の優位性を失うことを意味します.
public class Task implements Runnable
 {
      @Override
      public synchronized void run(){
        
  }
}

synchronizedは論理ユニット全体にロックをかけ、同時能力を失った.

3.異なるモニタロックと同じ方法

public class Task implements Runnable
{
private final Object obj = new Object();
   @Override
    public void run(){
        synchronized (obj){
            //doSomething();
     }
  }
}

public static void main(String [] args){
     for(int i = 0 ;;i<5i++){
      new Thread(Task::new).start();  
  } 
}

上述した5つのスレッドを構築し、同時に5つのRunnableインスタンスを構築し、Runnableは論理実行ユニットとしてThreadに伝達される.Synchronizedは、それに対応する役割ドメインを反発することはできません.上記のコードは,各スレッドが争うmonitor関連が独立しているため,反発の役割を果たすことは不可能である.

4.複数のロックが交差してデッドロックを引き起こす

private final Object o1 = new Object();
private final Object 02 = new Object();
private void write(){
 synchronized(o1){
      synchronized(o2){
  }
  }
}

public void read(){
     synchronized(o2){
      synchronized(o1){
  }
  }
}