2.2..9静的同期synchronizedメソッドとsynchronized(class)コードブロック

9189 ワード

synchronizedはstatic静的方法にも適用できるが、このように書くと、現在の*になる.JAvaファイルに対応するClassクラスがロックされます.
/**
 * @author wuyoushan
 * @date 2017/4/10.
 */
public class Service {

    synchronized  public static void printA(){
        try{
            System.out.println(" :"+Thread.currentThread().getName()
                    +" "+System.currentTimeMillis()+" printA");
            Thread.sleep(3000);
            System.out.println(" :"+Thread.currentThread().getName()
                    +" "+System.currentTimeMillis()+" printB");
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }

    synchronized  public static void printB(){
        System.out.println(" :"+Thread.currentThread().getName()
                +" "+System.currentTimeMillis()+" printA");
        System.out.println(" :"+Thread.currentThread().getName()
                +" "+System.currentTimeMillis()+" printB");
    }
}

 * @author wuyoushan
 * @date 2017/4/4.
 */
public class ThreadA extends Thread{

    @Override
    public void run() {
       super.run();
        Service.printA();
    }
}

/**
 * @author wuyoushan
 * @date 2017/4/4.
 */
public class ThreadB extends Thread{

    @Override
    public void run() {
        super.run();
        Service.printB();
    }
}

/**
 * @author wuyoushan
 * @date 2017/3/20.
 */
public class Run {
    public static void main(String[] args){
      ThreadA a=new ThreadA();
      a.setName("A");
      a.start();
      ThreadB b=new ThreadB();
      b.setName("B");
      b.start();
    }
}

プログラムの実行結果は次のとおりです.
 :A 1492993790410 printA
 :A 1492993793410 printA
 :B 1492993793410 printB
 :B 1492993793410 printB

実行結果から見ると、特に何もないが、同期の効果であり、synchronizedキーワードをstaticメソッドに追加して使用する効果と同じである.実際には、synchronizedキーワードをstaticに追加する静的メソッドはClassクラスにロックされ、synchronizedキーワードを非static静的メソッドに追加するとオブジェクトにロックされます.
同じロックではないことを確認
/**
 * @author wuyoushan
 * @date 2017/4/10.
 */
public class Service {

    synchronized  public static void printA(){
        try{
            System.out.println(" :"+Thread.currentThread().getName()
                    +" "+System.currentTimeMillis()+" printA");
            Thread.sleep(3000);
            System.out.println(" :"+Thread.currentThread().getName()
                    +" "+System.currentTimeMillis()+" printA");
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }

    synchronized  public static void printB(){
        System.out.println(" :"+Thread.currentThread().getName()
                +" "+System.currentTimeMillis()+" printB");
        System.out.println(" :"+Thread.currentThread().getName()
                +" "+System.currentTimeMillis()+" printB");
    }

    synchronized  public void printC(){
        System.out.println(" :"+Thread.currentThread().getName()
                +" "+System.currentTimeMillis()+" printC");
        System.out.println(" :"+Thread.currentThread().getName()
                +" "+System.currentTimeMillis()+" printC");
    }
}

/**
 * @author wuyoushan
 * @date 2017/4/4.
 */
public class ThreadA extends Thread{

    private Service service;

    public ThreadA(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
       super.run();
        service.printA();
    }
}

/**
 * @author wuyoushan
 * @date 2017/4/4.
 */
public class ThreadB extends Thread{

   private Service service;

    public ThreadB(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.printB();
    }
}

/**
 * @author wuyoushan
 * @date 2017/4/4.
 */
public class ThreadC extends Thread{

   private Service service;

    public ThreadC(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.printC();
    }
}

/**
 * @author wuyoushan
 * @date 2017/3/20.
 */
public class Run {
    public static void main(String[] args){
      Service service=new Service();
      ThreadA a=new ThreadA(service);
      a.setName("A");
      a.start();
      ThreadB b=new ThreadB(service);
      b.setName("B");
      b.start();
      ThreadC c=new ThreadC(service);
      c.setName("C");
      c.start();
    }
}

プログラムの実行結果は次のとおりです.
 :B 1492994339480 printB
 :B 1492994339480 printB
 :A 1492994339482 printA
 :C 1492994339482 printC
 :C 1492994339482 printC
 :A 1492994342482 printA

非同期の理由は、オブジェクト・ロックとクラスのすべてのオブジェクト・インスタンスに対して機能するClassロックがあるためです.
/**
 * @author wuyoushan
 * @date 2017/4/10.
 */
public class Service {

    synchronized  public static void printA(){
        try{
            System.out.println(" :"+Thread.currentThread().getName()
                    +" "+System.currentTimeMillis()+" printA");
            Thread.sleep(3000);
            System.out.println(" :"+Thread.currentThread().getName()
                    +" "+System.currentTimeMillis()+" printA");
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }

    synchronized  public static void printB(){
        System.out.println(" :"+Thread.currentThread().getName()
                +" "+System.currentTimeMillis()+" printB");
        System.out.println(" :"+Thread.currentThread().getName()
                +" "+System.currentTimeMillis()+" printB");
    }

}

/**
 * @author wuyoushan
 * @date 2017/4/4.
 */
public class ThreadA extends Thread{

    private Service service;

    public ThreadA(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
       super.run();
        service.printA();
    }
}

/**
 * @author wuyoushan
 * @date 2017/4/4.
 */
public class ThreadB extends Thread{

   private Service service;

    public ThreadB(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.printB();
    }
}

/**
 * @author wuyoushan
 * @date 2017/3/20.
 */
public class Run {
    public static void main(String[] args){
      Service service1=new Service();
      Service service2=new Service();
      ThreadA a=new ThreadA(service1);
      a.setName("A");
      a.start();
      ThreadB b=new ThreadB(service2);
      b.setName("B");
      b.start();
    }
}

プログラムの実行結果は次のとおりです.
 :A 1492995107179 printA
 :A 1492995110186 printA
 :B 1492995110186 printB
 :B 1492995110186 printB

synchronized(class)コードブロックを同期する役割は、synchronized staticメソッドと同じです.
/**
 * @author wuyoushan
 * @date 2017/4/10.
 */
public class Service {

    public static void printA(){
        synchronized (Service.class){
            try {
                System.out.println(" :" + Thread.currentThread().getName()
                        + " " + System.currentTimeMillis() + " printA");
                Thread.sleep(3000);
                System.out.println(" :" + Thread.currentThread().getName()
                        + " " + System.currentTimeMillis() + " printA");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void printB() {
        synchronized (Service.class) {
            System.out.println(" :" + Thread.currentThread().getName()
                    + " " + System.currentTimeMillis() + " printB");
            System.out.println(" :" + Thread.currentThread().getName()
                    + " " + System.currentTimeMillis() + " printB");
        }
    }

}

/**
 * @author wuyoushan
 * @date 2017/4/4.
 */
public class ThreadA extends Thread{

    private Service service;

    public ThreadA(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
       super.run();
        service.printA();
    }
}

/**
 * @author wuyoushan
 * @date 2017/4/4.
 */
public class ThreadB extends Thread{

   private Service service;

    public ThreadB(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.printB();
    }
}

/**
 * @author wuyoushan
 * @date 2017/3/20.
 */
public class Run {
    public static void main(String[] args){
      Service service1=new Service();
      Service service2=new Service();
      ThreadA a=new ThreadA(service1);
      a.setName("A");
      a.start();
      ThreadB b=new ThreadB(service2);
      b.setName("B");
      b.start();
    }
}

プログラムの実行結果は次のとおりです.
 :A 1492995444496 printA
 :A 1492995447497 printA
 :B 1492995447497 printB
 :B 1492995447497 printB

Javaマルチスレッドコアプログラミング技術から抜粋-2..9