2016-05-05 9 views
0

私は探検しようとしているstatic synchronized method私はそれがインスタンスではなく、クラスのロックを取得する理論的な概念を得た。しかし、私はそれを試すことができる例を作ることに失敗しました。Javaで実際に静的同期メソッドがどのように機能しますか?

ここで私はテストするコードを作成しましたが、両方のインスタンスが同時にstatic synchronized methodにアクセスしています。

class Demo{ 
    public static synchronized void a(){ 
     System.out.println("A Method " + Thread.currentThread().getName()); 
    } 
} 
public class StaticSyn{ 
    public static void main(String[] args){ 
     Demo obj = new Demo(); 
     Demo obj2 = new Demo(); 

     Thread one = new Thread(){ 
      @Override 
      public void run(){ 
       int i=0; 
       while(i<5){ 
        obj.a(); 
       try{ 
        Thread.sleep(100); 
       }catch(InterruptedException e){ 

       } 
        i++; 
       } 
      } 
     }; 
     Thread two = new Thread(new Runnable(){ 
      @Override 
      public void run(){ 
       int i=0; 
       while(i<5){ 
        obj2.a(); 
        try{ 
         Thread.sleep(100); 
        }catch(InterruptedException e){  } 
        i++; 
       } 
      } 
     }); 

     one.start(); 
     two.start(); 
    } 
} 

static synchronizedこの出力が表示されます。

A Method Thread-0 
A Method Thread-1 
A Method Thread-1 
A Method Thread-0 
A Method Thread-1 
A Method Thread-0 
A Method Thread-0 
A Method Thread-1 
A Method Thread-1 
A Method Thread-0 

いいえstaticキーワードこの出力を得ています。

A Method Thread-0 
A Method Thread-1 
A Method Thread-1 
A Method Thread-0 
A Method Thread-0 
A Method Thread-1 
A Method Thread-0 
A Method Thread-1 
A Method Thread-1 
A Method Thread-0 

だからどこに問題がありますか?どのようにして1つのオブジェクトが静的同期メソッドにアクセスしているかをテストできます。あなたは確かに、あなたは、あなたが次の出力に似同時に、このブロックを実行する2つのスレッドを持っていないことがわかります

public static synchronized void a(){ 
    System.out.println("Before sleep: A Method " + Thread.currentThread().getName()); 
    try{ 
     Thread.sleep(100); 
    } catch(InterruptedException e){ 
     Thread.currentThread().interrupt(); 
    } 
    System.out.println("After sleep: A Method " + Thread.currentThread().getName()); 
} 

+0

Demo'は '同期(Demo.class){...}'方法の本体をラップに相当する ''に静的synchronized'方法:これはそれを行う1つの方法です。 –

+0

@AndyTurnerはい私は知っていますが、なぜ両方のスレッドが別のオブジェクトで同じメソッドにアクセスしているのですか? –

+2

問題はありません。どちらのスレッドも* a *()内にありません。 – zapl

答えて

2

あなたはa()として次のあなたの方法でsleepを追加することができます2回連続Before sleep必要はありません:

Before sleep: A Method Thread-0 
After sleep: A Method Thread-0 
Before sleep: A Method Thread-1 
After sleep: A Method Thread-1 
Before sleep: A Method Thread-0 
After sleep: A Method Thread-0 
Before sleep: A Method Thread-1 
After sleep: A Method Thread-1 
Before sleep: A Method Thread-0 
After sleep: A Method Thread-0 
Before sleep: A Method Thread-1 
After sleep: A Method Thread-1 
Before sleep: A Method Thread-0 
After sleep: A Method Thread-0 
Before sleep: A Method Thread-1 
After sleep: A Method Thread-1 
Before sleep: A Method Thread-0 
After sleep: A Method Thread-0 
Before sleep: A Method Thread-1 
After sleep: A Method Thread-1 

static synchronized方法と​​方法の違いは何ですか?

主な違いは、アクセスを同期させるために使用されるオブジェクトです。

静的例えば

このこと:それが表すオブジェクトを使用static方法の場合すなわち

class Demo { 
    public static void a() { 
     synchronized (Demo.class) { 
      // Rest of the method 
     } 
    } 
} 

class Demo { 
    public static synchronized void a() { 
     // Rest of the method 
    } 
} 

これと同等であるとクラス自体を使用してアクセスを同期させます。

非静的

は、たとえば、これを行う:

class Demo { 
    public synchronized void a() { 
     // Rest of the method 
    } 
} 

がこれに相当しますnon static方法の場合、言い換えれば

class Demo { 
    public void a() { 
     synchronized (this) { 
      // Rest of the method 
     } 
    } 
} 

それが現在のインスタンスを使用していますアクセスを同期させるクラスのクラスです。

+0

本当にありがとうございましたが、ちょっと混乱しました。それらの違いを記述できるコードに 'static synchronized method'と' synchronized method'の例を書くことができますか? –

+0

確かに、ちょっと待ってください –

+0

@LetDoit私はそれが役に立ったら私の答えを更新しました –

0

メソッドコールが重複しないように、a()メソッドを長く実行する必要があります。

package com.example; 

public class Demo { 

    public static synchronized void a() { 
     for (int i = 0; i < 5; i++) { 
      System.out.println("A Method " + Thread.currentThread().getName()); 
      try { 
       Thread.sleep(100); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     final Demo obj = new Demo(); 
     final Demo obj2 = new Demo(); 

     Thread one = new Thread() { 
      @Override 
      public void run() { 
       obj.a(); // same as Demo.run() 
      } 
     }; 
     Thread two = new Thread() { 
      @Override 
      public void run() { 
       obj2.a(); // same as Demo.run() 
      } 
     }; 

     one.start(); 
     two.start(); 
    } 
} 
関連する問題