synchronizedはいったい何をロックしましたか?
synchronizedキーワードは、マルチスレッドコードを作成するjava開発者がよく使うキーワードであり、その主な役割は方法を同期させることであり、本論文は一連のテストを通して、このキーワードを深く理解することができることを望んでいる。
一.synchronizedの使い方。
始める前に、まずsynchronizedフィールドの使い方を調べます。
1.synchronizedは、メンバー方法を宣言するために使用できます。
二.synchronizedの役割
以下は具体的なテストを開始します。今回の主なテストはSynchronizedを声明方法に用いる時の主な役割です。以下のTestBean.javaはユーザーテストの主体類です。テストはこのような段階をめぐって行われます。
1,synchronized会は全体の種類に居住しますか?
Test.javaは、動的方法Aと動的方法Bのために2つのスレッドクラスを作成し、それぞれ2つのインスタンスを実行するsynchronized方法を作成した。
参照
I'm synchronized methodA
I'm synchronized methodB
Now field is:DSB
Now field is:DSA
それから、私たちはメーンメソッドを修正して、次のようにします。
参照
I'm synchronized methodA
Now field is:DSA
I'm synchronized methodB
Now field is:DSB
synchronizedはクラス全体をロックしていないが、ある実例だけをロックしています。異なる例の動的同期方法は同期しません。
2.プログラムがsynchronizedメソッドに入ったら、非同期方法は実行できますか?
Test.javaに非同期方法のスレッドを追加します。
参照
I'm synchronized methodA
I'm dynamic unsynchronized method
Now field is:DUS
Now field is:DSA
同期ロックは、非同期の方法ではないが、2つの方法を順番に実行したいなら、彼らのすべての束縛を必要とします。
3.synchronizedは動的方法と静的方法を同時にロックしますか?
まず、まずTestBeanを修正して、ダイナミックな方法に静的なメンバー変数の操作を加えます。
参照
I'm static synchronized methodB
Now field is:SSB
I'm static synchronized methodA
Now dynamicfield is:DSA
Now static field is:DSA
Now field is:SSA
静的方法と動的方法のロックは違っています。動的方法は動的方法とのみ同期します。静的方法は静的方法とのみ同期します。
要約すると、動的方法声明にsynchronizedフィールドを追加すると、このオブジェクトのインスタンスのロックが実行中に獲得され、この例のすべてのsynchronized方法はロックが解除される前に実行できなくなりますが、他の例では、この例の非同期方法と静的方法は影響を受けません。
これは本シリーズの最初の文章で、主に同じ種類の中で、声明方法にsynchronizedキーワードを入れる役割を説明しています。これからの文章では、synchronizedの他の用法と複数の種類の間でsynchronizedキーワードの役割をテストします。
一.synchronizedの使い方。
始める前に、まずsynchronizedフィールドの使い方を調べます。
1.synchronizedは、メンバー方法を宣言するために使用できます。
public synchronized int method () {
}
2.synchronizedはコードブロック、例えば
public void method {
synchronized(this) {
dosth();
}
}
注、括弧の中には必ず一例があります。二.synchronizedの役割
以下は具体的なテストを開始します。今回の主なテストはSynchronizedを声明方法に用いる時の主な役割です。以下のTestBean.javaはユーザーテストの主体類です。テストはこのような段階をめぐって行われます。
package org.sluggard.bolg.synctest;
/**
* , 2 ,
* 2 ,1 1 , A ,
* sleep10 , B , sleep1 , , sleep5 .
* @author Frank
*
*/
public class TestBean {
private String dynamicField;
private static String staticField;
/**
* A
* @param value
*/
public synchronized void dynamicSyncMethodA(String value) {
System.out.println("I'm synchronized methodA");
SleepUtil.sleep(10);
dynamicField = value;
System.out.println("Now field is : " + dynamicField);
}
/**
* B
*/
public synchronized void dynamicSyncMethodB(String value) {
System.out.println("I'm synchronized methodB");
SleepUtil.sleep(1);
dynamicField = value;
System.out.println("Now field is : " + dynamicField);
}
/**
* A
*/
public static synchronized void staticSyncMethodA(String value) {
System.out.println("I'm static synchronized methodA");
SleepUtil.sleep(10);
staticField = value;
System.out.println("Now field is : " + staticField);
}
/**
* B
*/
public static synchronized void staticSyncMethodB(String value) {
System.out.println("I'm static synchronized methodB");
SleepUtil.sleep(1);
staticField = value;
System.out.println("Now field is : " + staticField);
}
/**
*
*/
public void dynamicUnsyncMethod(String value) {
System.out.println("I'm dynamic unsynchronized method");
SleepUtil.sleep(5);
dynamicField = value;
System.out.println("Now field is : " + dynamicField);
}
/**
*
*/
public static void staticUnsyncMethod(String value) {
System.out.println("I'm static unsynchronized method");
SleepUtil.sleep(5);
staticField = value;
System.out.println("Now field is : " + staticField);
}
}
abstract class SleepUtil {
public static void sleep(int i){
try {
Thread.sleep(i*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
以下はこのようなテストコードの作成について、一連の問題を解決します。1,synchronized会は全体の種類に居住しますか?
Test.javaは、動的方法Aと動的方法Bのために2つのスレッドクラスを作成し、それぞれ2つのインスタンスを実行するsynchronized方法を作成した。
package org.sluggard.bolg.synctest;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
TestBean testBean1 = new TestBean();
TestBean testBean2 = new TestBean();
ThreadDSA dsa = new ThreadDSA(testBean1);
ThreadDSB dsb = new ThreadDSB(testBean2);
dsa.start();
SleepUtil.sleep(1);
dsb.start();
}
}
class ThreadDSA extends Thread{
@Override
public void run() {
testBean.dynamicSyncMethodA("DSA");
}
private TestBean testBean;
public ThreadDSA(TestBean testBean) {
super();
this.testBean = testBean;
}
}
class ThreadDSB extends Thread{
@Override
public void run() {
testBean.dynamicSyncMethodB("DSB");
}
private TestBean testBean;
public ThreadDSB(TestBean testBean) {
super();
this.testBean = testBean;
}
}
実行結果は以下の通りです参照
I'm synchronized methodA
I'm synchronized methodB
Now field is:DSB
Now field is:DSA
それから、私たちはメーンメソッドを修正して、次のようにします。
public static void main(String[] args) {
TestBean testBean = new TestBean();
ThreadDSA dsa = new ThreadDSA(testBean);
ThreadDSB dsb = new ThreadDSB(testBean);
dsa.start();
SleepUtil.sleep(1);
dsb.start();
}
実行結果は以下の通りです参照
I'm synchronized methodA
Now field is:DSA
I'm synchronized methodB
Now field is:DSB
synchronizedはクラス全体をロックしていないが、ある実例だけをロックしています。異なる例の動的同期方法は同期しません。
2.プログラムがsynchronizedメソッドに入ったら、非同期方法は実行できますか?
Test.javaに非同期方法のスレッドを追加します。
class ThreadDUS extends Thread{
@Override
public void run() {
testBean.dynamicUnsyncMethod("DUS");
}
private TestBean testBean;
public ThreadDUS(TestBean testBean) {
super();
this.testBean = testBean;
}
}
メールの方法を修正します。public static void main(String[] args) {
TestBean testBean = new TestBean();
ThreadDSA dsa = new ThreadDSA(testBean);
ThreadDUS dus = new ThreadDUS(testBean);
dsa.start();
SleepUtil.sleep(1);
dus.start();
}
実行結果は以下の通りです参照
I'm synchronized methodA
I'm dynamic unsynchronized method
Now field is:DUS
Now field is:DSA
同期ロックは、非同期の方法ではないが、2つの方法を順番に実行したいなら、彼らのすべての束縛を必要とします。
3.synchronizedは動的方法と静的方法を同時にロックしますか?
まず、まずTestBeanを修正して、ダイナミックな方法に静的なメンバー変数の操作を加えます。
public synchronized void dynamicSyncMethodA(String value) {
System.out.println("I'm synchronized methodA");
SleepUtil.sleep(10);
dynamicField = value;
staticField = value;
System.out.println("Now dynamicfield is : " + dynamicField + "
Now staticfield is : " + value);
}
同様に、静的同期法のためにスレッドクラスに参加し、class ThreadSSA extends Thread{
@Override
public void run() {
TestBean.staticSyncMethodA("SSA");
}
}
class ThreadSSB extends Thread{
@Override
public void run() {
TestBean.staticSyncMethodB("SSB");
}
}
メールの方法を修正します。public static void main(String[] args) {
TestBean testBean = new TestBean();
ThreadDSA dsa = new ThreadDSA(testBean);
ThreadSSB ssb = new ThreadSSB();
ThreadSSA ssa = new ThreadSSA();
dsa.start();
SleepUtil.sleep(1);
ssb.start();
ssa.start();
}
実行結果は以下の通りです参照
I'm static synchronized methodB
Now field is:SSB
I'm static synchronized methodA
Now dynamicfield is:DSA
Now static field is:DSA
Now field is:SSA
静的方法と動的方法のロックは違っています。動的方法は動的方法とのみ同期します。静的方法は静的方法とのみ同期します。
要約すると、動的方法声明にsynchronizedフィールドを追加すると、このオブジェクトのインスタンスのロックが実行中に獲得され、この例のすべてのsynchronized方法はロックが解除される前に実行できなくなりますが、他の例では、この例の非同期方法と静的方法は影響を受けません。
これは本シリーズの最初の文章で、主に同じ種類の中で、声明方法にsynchronizedキーワードを入れる役割を説明しています。これからの文章では、synchronizedの他の用法と複数の種類の間でsynchronizedキーワードの役割をテストします。