Javaのsynchronizedキーワードを理解する


1、synchronizedキーワードの役割ドメインは二つあります.
1)オブジェクトインスタンス内で、synchronized aMethod(){}は、複数のスレッドがこのオブジェクトに同時にアクセスすることを防止するsynchronizedメソッドです.(1つのオブジェクトに複数のsynchronizedメソッドがある場合、1つのスレッドが1つのsynchronizedメソッドにアクセスしている限り、他のスレッドはこのオブジェクトのいずれかのsynchronizedメソッドに同時にアクセスできません).この場合、異なるオブジェクトインスタンスのsynchronizedメソッドは干渉しません.つまり、他のスレッドは同じクラスの別のオブジェクトインスタンスにも同時にアクセスできます.例のsynchronizedメソッド;
2)あるクラスの範囲であり、synchronized static aStaticMethod{}は複数のスレッドがこのクラスのsynchronized staticメソッドに同時にアクセスすることを防止する.クラスのすべてのオブジェクトインスタンスに役立ちます.
2、synchronizedキーワードは、メソッドの前にsynchronizedキーワードを使用する以外に、synchronizedキーワードは、このブロックのリソースに対してのみ反発アクセスを行うことを示すメソッドのブロックにも使用することができる.
使用法はsynchronized(this){/*ブロック*/}で、その役割ドメインは現在のオブジェクトです.
3、synchronizedキーワードは継承できません.つまり、ベースクラスのメソッドsynchronized f(){}は、継承クラスで自動的にsynchronized f(){}ではなく、f(){}となります.クラスを継承するには、synchronizedメソッドを明示的に指定する必要があります.
4、疑問:
staticブロックがあることを知りました(その中のロードタイミングもよく分からないようですが、勉強する必要があります.
-eway-JavaEyeテクノロジーコミュニティ>」という文章の後にまた少しぼんやりしています:)、JVMの内在的なメカニズムを真剣に学ぶ必要があるのがこのような問題を理解する最も根本的な道かもしれません)、synchronizedブロックもありますが、synchronized staticブロックはありますか?クラスの役割ドメイン内のsynchronizedブロックはありますか?
今日、次の例を書いて、クラス範囲のsynchronizedまたはsynchronized staticブロックがあるかどうかを検証し、このようなブロックはないと結論した.すなわち、クラス範囲全体のあるリソースに対してsynchronizedを実行し、唯一の方法はsynchronized staticメソッドであり、このようにsynchronized static void ff()
{/*your code here*/}(littlebat後注:2007.2.13、友人V.Cの助けを得て、クラスの1つの方法の中で、クラス全体の範囲内のsynchronizedブロックが存在することができることをやっと知った.このように:synchronized(TestSynchronized.class){/*some code*/}
すべての例は以下の通りです.もし私の例と考えに何か不適切なところがあれば、友达に教えてもらいたいです.ありがとうございます.
インスタンス:TestSynchronized.java public class TestSynchronized {
 
  static{
    System.out.println("Step 1: a static block in class scope.");
  }
  static void f(){
    System.out.println("Step 2: a static method f() in class scope.");
  }
  synchronized static void ff(){ //The only way of synchronized a part in class scope.
    System.out.println("Step 3: a synchronized static method ff() in class scope.");
  }
  /*//No any synchronized block in class scope!
  synchronized {
    System.out.println("A synchronized block in class scope.");
  }
  */
  /*//No any synchronized static block in class scope!
  synchronized static {
    System.out.println("A synchronized static block in class scope.");
  }
  */
  
  void fff(){
    synchronized(this){
      System.out.println("Step 4: a synchronized block in method fff() in object scope.");
    }
  }
  
  synchronized void ffff(){
    System.out.println("Step 5: a synchronized method ffff() in object scope.");
  }
  
  public static void main(String[] args) {
    TestSynchronized.f();
    TestSynchronized.ff();
    (new TestSynchronized()).fff();
    (new TestSynchronized()).ffff();
    }
}
   :

Step 1: a static block in class scope.
Step 2: a static method f() in class scope.
Step 3: a synchronized static method ff() in class scope.
Step 4: a synchronized block in method fff() in object scope.
Step 5: a synchronized method ffff() in object scope.
The format below can implement synchronizing in Class scope:
synchronized (TestSynchronized.Class) {
}
Yes, I can get synchronized block in a method in class scope
(Note: TestSynchronized.class isn't TestSynchronized.Class):
void fffff(){
    synchronized (TestSynchronized.class) {
      System.out.println("Step 6: a synchronized block in method fffff() in class scope.");
    }
  }
---------------------------------------------------synchronized(this)のいくつかの :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------synchronizedキーワードは、synchronizedメソッドとsynchronizedブロックの2つの い を む.  1. synchronizedメソッドは、メソッド にsynchronizedキーワードを することによってsynchronizedメソッドを します. えば、public synchronized void accessVal(int newVal);synchronizedメソッドはクラスメンバー へのアクセスを する: クラスインスタンスはロックに し、 synchronizedメソッドはメソッドを び すクラスインスタンスのロックを しなければならない.そうしないと、 するスレッドがブロックされ、メソッドが されると、ロックが され、メソッドから るまでロックが され、その ブロックされたスレッドがロックを することができる. な に ります.このメカニズムは、 クラスのインスタンスに して じ を する.synchronizedとして されたすべてのメンバー のうち、クラスインスタンスに するロックが1つしか できないため、 な にあるメンバー は、クラスメンバー へのアクセス を に します.(クラスメンバー にアクセス なすべてのメソッドがsynchronizedとして されている ).Javaでは、クラスインスタンスだけでなく、 クラスにもロックが しているため、クラスの メンバー をsynchronizedとして して、クラスの メンバー へのアクセスを することもできます.synchronizedメソッドの : きな メソッドをsynchronizedと すると、 に きく します. 、スレッドクラスのメソッドrun()をsynchronizedと すると、スレッドのライフサイクル で されているため、このクラスのsynchronizedメソッドの び しは しません.もちろん、クラスメンバー にアクセスするコードを のメソッドに してsynchronizedと し、メインメソッドで び すことでこの を することができますが、Javaはsynchronizedブロックというより い を しています.  2. synchronizedブロックsynchronizedキーワードによりsynchronizedブロックを します. は のとおりです.synchronized(syncObject){//アクセス を するコード}synchronizedブロックはこのようなコードブロックです.コードは、 のようにクラスインスタンスまたはクラスであってもよいオブジェクトsyncObjectのロックを する があり、 なメカニズムは のとおりである. のコードブロックに して、ロックされたオブジェクトを に できるため、 が い.1、2つの スレッドが じオブジェクトobjectのsynchronized(this) コードブロックにアクセスする 、1 に1つのスレッドしか できません. のスレッドは、 のスレッドがこのコードブロックを するまで たなければなりません. 、しかしながら、あるスレッドがobjectのsynchronized(this) コードブロックにアクセスする 、 のスレッドは、object の synchronized(this) コードブロックにアクセスすることができる. 、 に なのは、1つのスレッドがobjectのsynchronized(this) コードブロックにアクセスすると、 のスレッドがobject の のすべてのsynchronized(this) コードブロックへのアクセスがブロックされることである. 、 の は、 の コードブロックにも に される.すなわち、objectのsynchronized(this) コードブロックにスレッドがアクセスすると、このobjectのオブジェクトロックが られる.その 、objectオブジェクトのすべての コード への のスレッドのアクセスが にブロックされる. 、 の は の ロックに しても に する. :1、2つの スレッドが じオブジェクトobjectのsynchronized コードブロックにアクセスすると、1 に1つのスレッドしか できません. のスレッドは、 のスレッドがこのコードブロックを するまで たなければなりません.package ths;
public class Thread1 implements Runnable {
public void run() {
synchronized(this) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
}
}
}
public static void main(String[] args) {
Thread1 t1 = new Thread1();
Thread ta = new Thread(t1, "A");
Thread tb = new Thread(t1, "B");
ta.start();
tb.start();
}
}
:A synchronized loop 0
A synchronized loop 1
A synchronized loop 2
A synchronized loop 3
A synchronized loop 4
B synchronized loop 0
B synchronized loop 1
B synchronized loop 2
B synchronized loop 3
B synchronized loop 4

   、 , object synchronized(this) , object

   synchronized(this) 。

package ths;
public class Thread2 {
public void m4t1() {
synchronized(this) {
int i = 5;
while( i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
}
public void m4t2() {
int i = 5;
while( i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
public static void main(String[] args) {
final Thread2 myt2 = new Thread2();
Thread t1 = new Thread(
new Runnable() {
public void run() {
myt2.m4t1();
}
}, "t1"
);
Thread t2 = new Thread(
new Runnable() {
public void run() {
myt2.m4t2();
}
}, "t2"
);
t1.start();
t2.start();
}
}
:t 1:4 t 2:4 t 1:3 t 2:3 t 1:2 t 2:2 t 1:1 t 2:1 t 1:0 t 2:0 、 に なのは、1つのスレッドがobjectのsynchronized(this) コードブロックにアクセスするとき、 のスレッドはobject の のsynchronized(this) コードブロックへのアクセスをブロックします.//Thread 2を する.m 4 t 2() :public void m4t2() {
synchronized(this) {
int i = 5;
while( i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
}
:t 1:4 t 1:3 t 1:2 t 1:1 t 1:0 t 2:4 t 2:3 t 2:2 t 2:1 t 2:0 、 3 と に の コードブロックが される.すなわち、objectのsynchronized(this) コードブロックにスレッドがアクセスすると、このobjectのオブジェクトロックが られる.その 、objectオブジェクトのすべての コード への のスレッドのアクセスが にブロックされる.//Thread 2を する.m 4 t 2() は、public synchronized void m4t2() {
int i = 5;
while( i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}