synchronizedによる同時性への影響

5345 ワード

1はじめに

  • 非静的方法の同期ロックは、現在のオブジェクト(this)(オブジェクトロック)
  • である.
  • 静的方法の同期ロックは、現在のクラスのバイトコード(クラスロック)
  • である.
  • 異なるロック間で
  • を併発することができる.

    2同一対象内


    このセクションの主クラスとリソースクラスは次のとおりです.
    class Resorce{ // 
    	static int x=0;
    	static int y=0;
    }
    
    public class Main {
    	public static void main(String[] args) {
    		Operate op=new Operate();
    		Thread t1=new Thread() {
    			public void run() {
    				op.fun1();
    			}
    		};
    		Thread t2=new Thread() {
    			public void run() {
    				op.fun2();
    			}
    		};
    		t1.start();
    		t2.start();
    	}
    }

    2.1 synchronizedによって修飾された2つの非staticメソッドと、修飾されていない1つのメソッドを同時に実行できますか?(同時)
    (この例では、2つのメソッドが同じリソースにアクセスし、同時に実行できます.異なるリソースにアクセスすれば、同時に実行できます)
    class Operate{
    	void fun1() {
    		for(int i=0;i<3;i++) {
    			Resorce.x++;
    			for(int j=0;j<1000;j++); // 
    			System.out.println("t1-uux:"+Resorce.x);
    		}
    	}
    	
    	synchronized void fun2() {
    		for(int i=0;i<3;i++) {
    			Resorce.x++;
    			for(int j=0;j<1000;j++); // 
    			System.out.println("t2-sux:"+Resorce.x);
    		}
    	}
    }

    実行結果:
    t1-sux:2
    t2-uux:2
    t2-uux:4
    t1-sux:3
    t1-sux:6
    t2-uux:5

    sux:synchronizedによって修飾され、staticによって修飾されず、リソースはxである.
    uux:synchronizedによって修飾されず、staticによって修飾されず、リソースはxである.
    2.2 2つの非staticメソッドはsynchronizedによって修飾されていますが、同時に使用できますか?(同時実行不可)
    (この例では、2つのメソッドが異なるリソースにアクセスし、同時に実行できません.同じリソースにアクセスしても、同時に実行できません)
    class Operate{
    	synchronized void fun1() {
    		for(int i=0;i<3;i++) {
    			Resorce.x++;
    			for(int j=0;j<1000;j++); // 
    			System.out.println("t1-sux:"+Resorce.x);
    		}
    	}
    	
    	synchronized void fun2() {
    		for(int i=0;i<3;i++) {
    			Resorce.y++;
    			for(int j=0;j<1000;j++); // 
    			System.out.println("t2-suy:"+Resorce.y);
    		}
    	}
    }

    実行結果:
    t1-sux:1
    t1-sux:2
    t1-sux:3
    t2-suy:1
    t2-suy:2
    t2-suy:3

    sux:synchronizedによって修飾され、staticによって修飾されず、リソースはxである.
    suy:synchronizedによって修飾され、staticによって修飾されず、リソースはyである.
    2.3 2つのsynchronizedメソッド、1つはstaticによって修飾され、1つは修飾されていません.同時に実行できますか?(同時)
    (この例では、2つのメソッドが同じリソースにアクセスし、同時に実行できます.異なるリソースにアクセスすれば、同時に実行できます)
    class Operate{
    	synchronized void fun1() {
    		for(int i=0;i<3;i++) {
    			Resorce.x++;
    			for(int j=0;j<1000;j++); // 
    			System.out.println("t1-sux:"+Resorce.x);
    		}
    	}
    	
    	synchronized static void fun2() {
    		for(int i=0;i<3;i++) {
    			Resorce.x++;
    			for(int j=0;j<1000;j++); // 
    			System.out.println("t2-ssx:"+Resorce.x);
    		}
    	}
    }

    実行結果:
    t1-ssx:2
    t1-ssx:3
    t2-sux:2
    t1-ssx:4
    t2-sux:5
    t2-sux:6

    ssx:synchronizedによって修飾され、staticによって修飾され、資源はxである.
    sux:synchronizedによって修飾され、staticによって修飾されず、リソースはxである.
    2.4 2つのstaticメソッドはsynchronizedによって修飾されていますが、同時に使用できますか?(同時実行不可)
    (この例では、2つのメソッドが異なるリソースにアクセスし、同時に実行できません.同じリソースにアクセスしても、同時に実行できません)
    class Operate{
    	synchronized static void fun1() {
    		for(int i=0;i<3;i++) {
    			Resorce.x++;
    			for(int j=0;j<1000;j++); // 
    			System.out.println("t1-ssx:"+Resorce.x);
    		}
    	}
    	
    	synchronized static void fun2() {
    		for(int i=0;i<3;i++) {
    			Resorce.y++;
    			for(int j=0;j<1000;j++); // 
    			System.out.println("t2-ssy:"+Resorce.y);
    		}
    	}
    }

    実行結果:
    t1-ssx:1
    t1-ssx:2
    t1-ssx:3
    t2-ssy:1
    t2-ssy:2
    t2-ssy:3

    ssx:synchronizedによって修飾され、staticによって修飾され、資源はxである.
    ssy:synchronizedによって修飾され、staticによって修飾され、リソースはyである.

    3異なるオブジェクト間


    2節の2つの同時性がない場合について説明します.主クラスとリソースクラスは次のとおりです.
    class Resorce{ // 
    	static int x=0;
    	static int y=0;
    }
    
    public class Main {
    	public static void main(String[] args) {
    		Operate op1=new Operate();
    		Operate op2=new Operate();
    		Thread t1=new Thread() {
    			public void run() {
    				op1.fun1();
    			}
    		};
    		Thread t2=new Thread() {
    			public void run() {
    				op2.fun2();
    			}
    		};
    		t1.start();
    		t2.start();
    	}
    }

    3.1 2つの非staticメソッドはsynchronizedによって修飾されていますが、同時に使用できますか?(同時)
    (この例では、2つのメソッドが同じリソースにアクセスし、同時に実行できます.異なるリソースにアクセスすれば、同時に実行できます)
    class Operate{
    	synchronized void fun1() {
    		for(int i=0;i<3;i++) {
    			Resorce.x++;
    			for(int j=0;j<1000;j++); // 
    			System.out.println("t1-sux:"+Resorce.x);
    		}
    	}
    
    	synchronized void fun2() {
    		for(int i=0;i<3;i++) {
    			Resorce.x++;
    			for(int j=0;j<1000;j++); // 
    			System.out.println("t2-sux:"+Resorce.x);
    		}
    	}
    }

    実行結果:
    t2-sux:2
    t1-sux:2
    t1-sux:4
    t1-sux:5
    t2-sux:3
    t2-sux:6

    sux:synchronizedによって修飾され、staticによって修飾されず、リソースはxである.
    3.2 2つのstaticメソッドはsynchronizedによって修飾されていますが、同時に使用できますか?(同時実行不可)
    (この例では、2つのメソッドが異なるリソースにアクセスし、同時に実行できません.同じリソースにアクセスしても、同時に実行できません)
    class Operate{
    	synchronized static void fun1() {
    		for(int i=0;i<3;i++) {
    			Resorce.x++;
    			for(int j=0;j<1000;j++); // 
    			System.out.println("t1-ssx:"+Resorce.x);
    		}
    	}
    	
    	synchronized static void fun2() {
    		for(int i=0;i<3;i++) {
    			Resorce.y++;
    			for(int j=0;j<1000;j++); // 
    			System.out.println("t2-ssy:"+Resorce.y);
    		}
    	}
    }

    実行結果:
    t1-ssx:1
    t1-ssx:2
    t1-ssx:3
    t2-ssy:1
    t2-ssy:2
    t2-ssy:3

    ssx:synchronizedによって修飾され、staticによって修飾され、資源はxである.
    ssy:synchronizedによって修飾され、staticによって修飾され、リソースはyである.

    4注意事項


    ここでのリソースは臨界リソースではなく、臨界リソースは信号量によってアクセスを制御する.