Javaはマルチスレッド(III):同期

マルチスレッドセーフで

ダーティ読み取り:データを読むために主要なアクセスを変更するには、同じオブジェクトのインスタンス変数に複数のスレッド、後に修正されます。

ThreadDomain16クラス

public class ThreadDomain16 {
    private int num = 0;

    public void addNum(String userName)
    {
        try
        {
            if ("a".equals(userName))
            {
                num = 100;
                System.out.println("a set over!");
                Thread.sleep(2000);
            }
            else
            {
                num = 200;
                System.out.println("b set over!");
            }
            System.out.println(userName + " num = " + num);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}

MyThread16_0クラス

public class MyThread16_0 extends Thread{
    private ThreadDomain16 td;

    public MyThread16_0(ThreadDomain16 td)
    {
        this.td = td;
    }

    public void run()
    {
        td.addNum("a");
    }
}

MyThread16_1クラスは
MyThread16_0とMyThread16_1スレッドを開始します

public class MyThread16_1 extends Thread {
    private ThreadDomain16 td;

    public MyThread16_1(ThreadDomain16 td)
    {
        this.td = td;
    }

    public void run()
    {
        td.addNum("b");
    }

}

mainメソッド

public class MyThread16_main_0 {
    public static void main(String[] args)
    {
        ThreadDomain16 td = new ThreadDomain16();
        MyThread16_0 mt0 = new MyThread16_0(td);
        MyThread16_1 mt1 = new MyThread16_1(td);
        mt0.start();
        mt1.start();
    }
}

次のように出力結果があります

a set over!
b set over!
b num = 200
a num = 200

出力は、理想的にはNUM = 100、BのNUM =なければならない 200、 NUM = 200の結果。
私たちは、業務プロセスを分析する必要があり、MyThread16_0はスレッドnumの200を変更MyThread16_1、中MyThread16_0睡眠中2秒間スリープし、その後、スレッドnumは100です修正します。リードNUM MyThread16_0も200になります。最後に、最初の出力のB NUM = 200、および= 200 NUMを出力します。彼女は、ダーティリードが登場しました。
この問題は非常に簡単です解決するために、我々は()addNumでsynchronizedキーワードが先行します

public synchronized void addNum(String userName)
    {
        try
        {
            if ("a".equals(userName))
            {
                num = 100;
                System.out.println("a set over!");
                Thread.sleep(2000);
            }
            else
            {
                num = 200;
                System.out.println("b set over!");
            }
            System.out.println(userName + " num = " + num);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }

次のように出力結果があります

a set over!
a num = 100
b set over!
b num = 200

スレッドがロックを解放するまで順次印刷、スレッドが最初のロックを取得する同期修正方法を実行するためのスレッドのロックを形成する方法の同期修正は、他のスレッドが待機しているスレッドは、実装前にロックを取得し、待機しなければなりません。

ロックオブジェクト

同步情况次に、以下の主な方法

public class MyThread16_main_1 {
    public static void main(String[] args)
    {
        ThreadDomain16 td0 = new ThreadDomain16();
        ThreadDomain16 td1 = new ThreadDomain16();
        MyThread16_0 mt0 = new MyThread16_0(td0);
        MyThread16_1 mt1 = new MyThread16_1(td1);
        mt0.start();
        mt1.start();
    }
}

業績

a set over!
b set over!
b num = 200
a num = 100

CROSSプリントについて説明同期ロックオブジェクトの終了を待って、代わりの方法をロックせずにBの実行、表示されます。ここでは、2つのThreadDomain16オブジェクトを宣言し、その2つのオブジェクトがない制約の「ロック解除を待つ」、ロックがあります。
だから我々は、synchronizedキーワードを削除するためにaddNumメソッドの前に入れ、异步情况下の
業績は次のように

a set over!
b set over!
b num = 200
a num = 100

あなたはまだダーティリード現象を回避、何同期ヘルプはありません、見ることができます。各オブジェクトインスタンスの変数NUM自身の所持。しかし、このソリューションは、複数のオブジェクトが推奨されていない宣言する必要があります。

メソッドとオブジェクト同期ロック

今例を見て、同期修正する方法がある、さらに修正された方法が同期されていない
ThreadDomain17クラス

public class ThreadDomain17 {
    public synchronized void methodA()
    {
        try
        {
            System.out.println("开始 methodA, 线程名称 = " +
                    Thread.currentThread().getName());
            Thread.sleep(5000);
            System.out.println("结束 methodA, 线程名称 = " +
                    Thread.currentThread().getName());
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }

    public void methodB()
    {
        try
        {
            System.out.println("开始 methodB, 线程名称 = " +
                    Thread.currentThread().getName());
            Thread.sleep(5000);
            System.out.println("结束 methodB, 线程名称 = " +
                    Thread.currentThread().getName());
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}

MyThread17_0クラス

public class MyThread17_0 extends Thread{
    private ThreadDomain17 td;

    public MyThread17_0(ThreadDomain17 td)
    {
        this.td = td;
    }

    public void run()
    {
        td.methodA();
    }
}

MyThread17_1クラス

public class MyThread17_1 extends Thread{
    private ThreadDomain17 td;

    public MyThread17_1(ThreadDomain17 td)
    {
        this.td = td;
    }

    public void run()
    {
        td.methodB();
    }
}

mainメソッド

public class MyThread17_main {
    public static void main(String[] args) {
        ThreadDomain17 td = new ThreadDomain17();
        MyThread17_0 mt0 = new MyThread17_0(td);
        mt0.setName("A");
        MyThread17_1 mt1 = new MyThread17_1(td);
        mt1.setName("B");
        mt0.start();
        mt1.start();
    }
}

結果は以下のとおりであります

开始 methodB, 线程名称 = B
开始 methodA, 线程名称 = A
结束 methodA, 线程名称 = A
结束 methodB, 线程名称 = B

あなたが見ることができ、methodB非同期メソッドが非同期的に呼び出されます。
td.methodAに実行クラスMyThread17_1の方法();
出力は、以下

开始 methodA, 线程名称 = A
结束 methodA, 线程名称 = A
开始 methodA, 线程名称 = B
结束 methodA, 线程名称 = B

同期方法で実行されるスレッドが再び同期を実行するために待機します。
スレッドはオブジェクトが非同期的に呼び出すことができるThreadDomain17オブジェクトロックThreadDomain17、Bのスレッドが非同期メソッドを保持し、
スレッドがThreadDomain17は、Bのスレッドが待機するオブジェクトThreadDomain17同期メソッドを呼び出して、オブジェクトのロックを保持して、

バックrunメソッドのMyThread17_1クラスは、TDします。 methodB(); methodBメソッドは次のように出力結果であり、同期キーワードでクラスをThreadDomain17

开始 methodA, 线程名称 = A
结束 methodA, 线程名称 = A
开始 methodB, 线程名称 = B
结束 methodB, 线程名称 = B

これはよく、同期ロックを取得するために、実行の最初のスレッドが理解され、そしてそのスレッドは、すべての操作を実行するスレッドが同期されている待って、終了する必要があります。

同期ロックリエントラント

スレッドロックがオブジェクトを与える際に再入可能ロックは、同期され、オブジェクトのロックが再び適用され、オブジェクトのロックを取得することができます。
ThreadDomain18クラス

public class ThreadDomain18 {
    public synchronized void print1()
    {
        System.out.println("ThreadDomain18.print1()");
        print2();
    }

    public synchronized void print2()
    {
        System.out.println("ThreadDomain18.print2()");
        print3();
    }

    public synchronized void print3()
    {
        System.out.println("ThreadDomain18.print3()");
    }
}

MyThread18クラス

public class MyThread18 extends Thread{
    public void run()
    {
        ThreadDomain18 td = new ThreadDomain18();
        td.print1();
    }

    public static void main(String[] args)
    {
        MyThread18 mt = new MyThread18();
        mt.start();
    }
    
}

結果は以下の通りであります

ThreadDomain18.print1()
ThreadDomain18.print2()
ThreadDomain18.print3()

説明結果は、MyThread18はロックされた場合には、ロックをオブジェクトへの複数回取得します

異常なリリースロック

ThreadDomain19クラス

public class ThreadDomain19 {
    public synchronized void testMethod()
    {
        try
        {
            System.out.println("进入 ThreadDomain19.testMethod(), currentThread = " +
                    Thread.currentThread().getName());
            long l = 5;
            while (true)
            {
                long lo = 2 / l;
                Thread.sleep(1000);
                l--;
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

MyThread19クラス

public class MyThread19 extends Thread {
    private ThreadDomain19 td;

    public MyThread19(ThreadDomain19 td)
    {
        this.td = td;
    }

    public void run()
    {
        td.testMethod();
    }

    public static void main(String[] args)
    {
        ThreadDomain19 td = new ThreadDomain19();
        MyThread19 mt0 = new MyThread19(td);
        MyThread19 mt1 = new MyThread19(td);
        mt0.start();
        mt1.start();
    }
}

次のように出力結果があります

进入 ThreadDomain19.testMethod(), currentThread = Thread-1
java.lang.ArithmeticException: / by zero
进入 ThreadDomain19.testMethod(), currentThread = Thread-0
    at com.advance.MultiThread3.ThreadDomain19.testMethod(ThreadDomain19.java:18)
    at com.advance.MultiThread3.MyThread19.run(MyThread19.java:18)
java.lang.ArithmeticException: / by zero
    at com.advance.MultiThread3.ThreadDomain19.testMethod(ThreadDomain19.java:18)
    at com.advance.MultiThread3.MyThread19.run(MyThread19.java:18)

それは上記分かるように、異常と、ロックが自動的に解除されます。スレッド-1は、単に例外をスロー終えていたが、今回スレッド-1リリースロックは、スレッド0が実行を開始しました。

メソッドの同期ブロック

ThreadDomain20クラス

public class ThreadDomain20 extends Thread{
    public void doLongTimeTask() throws Exception
    {
        for (int i = 0; i < 100; i++)
        {
            System.out.println("nosynchronized threadName = " +
                    Thread.currentThread().getName() + ", i = " + (i + 1));
        }
        System.out.println();
        synchronized (this){
            for (int i = 0; i < 100; i++)
            {
                System.out.println("synchronized threadName = " +
                        Thread.currentThread().getName() + ", i = " + (i + 1));
            }
        }
    }
    
}

MyThread20クラス

public class MyThread20 extends Thread{
    private ThreadDomain20 td;

    public MyThread20(ThreadDomain20 td)
    {
        this.td = td;
    }

    public void run()
    {
        try
        {
            td.doLongTimeTask();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void main(String[] args)
    {
        ThreadDomain20 td = new ThreadDomain20();
        MyThread20 mt0 = new MyThread20(td);
        mt0.setName("A");
        MyThread20 mt1 = new MyThread20(td);
        mt1.setName("B");
        mt0.start();
        mt1.start();
    }

}

結果は以下のとおりであります

nosynchronized threadName = A, i = 1
nosynchronized threadName = B, i = 1
nosynchronized threadName = A, i = 2
nosynchronized threadName = B, i = 2
nosynchronized threadName = A, i = 3
nosynchronized threadName = B, i = 3
nosynchronized threadName = A, i = 4
nosynchronized threadName = B, i = 4
nosynchronized threadName = A, i = 5
nosynchronized threadName = B, i = 5
nosynchronized threadName = A, i = 6
nosynchronized threadName = B, i = 6
nosynchronized threadName = A, i = 7
nosynchronized threadName = B, i = 7
nosynchronized threadName = A, i = 8
nosynchronized threadName = B, i = 8
nosynchronized threadName = A, i = 9
nosynchronized threadName = B, i = 9
nosynchronized threadName = A, i = 10
nosynchronized threadName = B, i = 10
nosynchronized threadName = A, i = 11
nosynchronized threadName = B, i = 11
nosynchronized threadName = A, i = 12
nosynchronized threadName = B, i = 12
nosynchronized threadName = A, i = 13
nosynchronized threadName = B, i = 13
nosynchronized threadName = A, i = 14
nosynchronized threadName = B, i = 14
nosynchronized threadName = A, i = 15
nosynchronized threadName = A, i = 16
nosynchronized threadName = A, i = 17
nosynchronized threadName = A, i = 18
nosynchronized threadName = B, i = 15
nosynchronized threadName = A, i = 19
nosynchronized threadName = B, i = 16
nosynchronized threadName = A, i = 20
nosynchronized threadName = B, i = 17
nosynchronized threadName = A, i = 21
nosynchronized threadName = B, i = 18
nosynchronized threadName = A, i = 22
nosynchronized threadName = B, i = 19
nosynchronized threadName = A, i = 23
nosynchronized threadName = A, i = 24
nosynchronized threadName = B, i = 20
nosynchronized threadName = A, i = 25
nosynchronized threadName = B, i = 21
nosynchronized threadName = A, i = 26
nosynchronized threadName = B, i = 22
nosynchronized threadName = A, i = 27
nosynchronized threadName = B, i = 23
nosynchronized threadName = A, i = 28
nosynchronized threadName = B, i = 24
nosynchronized threadName = A, i = 29
nosynchronized threadName = B, i = 25
nosynchronized threadName = A, i = 30
nosynchronized threadName = B, i = 26
nosynchronized threadName = A, i = 31
nosynchronized threadName = A, i = 32
nosynchronized threadName = B, i = 27
nosynchronized threadName = A, i = 33
nosynchronized threadName = B, i = 28
nosynchronized threadName = A, i = 34
nosynchronized threadName = B, i = 29
nosynchronized threadName = A, i = 35
nosynchronized threadName = B, i = 30
nosynchronized threadName = A, i = 36
nosynchronized threadName = B, i = 31
nosynchronized threadName = A, i = 37
nosynchronized threadName = B, i = 32
nosynchronized threadName = A, i = 38
nosynchronized threadName = A, i = 39
nosynchronized threadName = B, i = 33
nosynchronized threadName = A, i = 40
nosynchronized threadName = B, i = 34
nosynchronized threadName = A, i = 41
nosynchronized threadName = B, i = 35
nosynchronized threadName = A, i = 42
nosynchronized threadName = B, i = 36
nosynchronized threadName = A, i = 43
nosynchronized threadName = B, i = 37
nosynchronized threadName = A, i = 44
nosynchronized threadName = B, i = 38
nosynchronized threadName = A, i = 45
nosynchronized threadName = B, i = 39
nosynchronized threadName = A, i = 46
nosynchronized threadName = B, i = 40
nosynchronized threadName = A, i = 47
nosynchronized threadName = B, i = 41
nosynchronized threadName = A, i = 48
nosynchronized threadName = B, i = 42
nosynchronized threadName = A, i = 49
nosynchronized threadName = B, i = 43
nosynchronized threadName = A, i = 50
nosynchronized threadName = B, i = 44

nosynchronized threadName = B, i = 45
synchronized threadName = A, i = 1
nosynchronized threadName = B, i = 46
synchronized threadName = A, i = 2
nosynchronized threadName = B, i = 47
synchronized threadName = A, i = 3
nosynchronized threadName = B, i = 48
synchronized threadName = A, i = 4
nosynchronized threadName = B, i = 49
nosynchronized threadName = B, i = 50

synchronized threadName = A, i = 5
synchronized threadName = A, i = 6
synchronized threadName = A, i = 7
synchronized threadName = A, i = 8
synchronized threadName = A, i = 9
synchronized threadName = A, i = 10
synchronized threadName = A, i = 11
synchronized threadName = A, i = 12
synchronized threadName = A, i = 13
synchronized threadName = A, i = 14
synchronized threadName = A, i = 15
synchronized threadName = A, i = 16
synchronized threadName = A, i = 17
synchronized threadName = A, i = 18
synchronized threadName = A, i = 19
synchronized threadName = A, i = 20
synchronized threadName = A, i = 21
synchronized threadName = A, i = 22
synchronized threadName = A, i = 23
synchronized threadName = A, i = 24
synchronized threadName = A, i = 25
synchronized threadName = A, i = 26
synchronized threadName = A, i = 27
synchronized threadName = A, i = 28
synchronized threadName = A, i = 29
synchronized threadName = A, i = 30
synchronized threadName = A, i = 31
synchronized threadName = A, i = 32
synchronized threadName = A, i = 33
synchronized threadName = A, i = 34
synchronized threadName = A, i = 35
synchronized threadName = A, i = 36
synchronized threadName = A, i = 37
synchronized threadName = A, i = 38
synchronized threadName = A, i = 39
synchronized threadName = A, i = 40
synchronized threadName = A, i = 41
synchronized threadName = A, i = 42
synchronized threadName = A, i = 43
synchronized threadName = A, i = 44
synchronized threadName = A, i = 45
synchronized threadName = A, i = 46
synchronized threadName = A, i = 47
synchronized threadName = A, i = 48
synchronized threadName = A, i = 49
synchronized threadName = A, i = 50
synchronized threadName = B, i = 1
synchronized threadName = B, i = 2
synchronized threadName = B, i = 3
synchronized threadName = B, i = 4
synchronized threadName = B, i = 5
synchronized threadName = B, i = 6
synchronized threadName = B, i = 7
synchronized threadName = B, i = 8
synchronized threadName = B, i = 9
synchronized threadName = B, i = 10
synchronized threadName = B, i = 11
synchronized threadName = B, i = 12
synchronized threadName = B, i = 13
synchronized threadName = B, i = 14
synchronized threadName = B, i = 15
synchronized threadName = B, i = 16
synchronized threadName = B, i = 17
synchronized threadName = B, i = 18
synchronized threadName = B, i = 19
synchronized threadName = B, i = 20
synchronized threadName = B, i = 21
synchronized threadName = B, i = 22
synchronized threadName = B, i = 23
synchronized threadName = B, i = 24
synchronized threadName = B, i = 25
synchronized threadName = B, i = 26
synchronized threadName = B, i = 27
synchronized threadName = B, i = 28
synchronized threadName = B, i = 29
synchronized threadName = B, i = 30
synchronized threadName = B, i = 31
synchronized threadName = B, i = 32
synchronized threadName = B, i = 33
synchronized threadName = B, i = 34
synchronized threadName = B, i = 35
synchronized threadName = B, i = 36
synchronized threadName = B, i = 37
synchronized threadName = B, i = 38
synchronized threadName = B, i = 39
synchronized threadName = B, i = 40
synchronized threadName = B, i = 41
synchronized threadName = B, i = 42
synchronized threadName = B, i = 43
synchronized threadName = B, i = 44
synchronized threadName = B, i = 45
synchronized threadName = B, i = 46
synchronized threadName = B, i = 47
synchronized threadName = B, i = 48
synchronized threadName = B, i = 49
synchronized threadName = B, i = 50

結論:
スレッド同期アクセス方法は、ブロックBのスレッドが依然として非同期メソッドブロックの内容にアクセスすることができ、
スレッドが同期メソッドブロックにアクセスするとき、Bブロックのスレッドが同期メソッドがブロックされるアクセス。

同期ブロックと同期する方法の方法

一貫した結果は、キーワードとブロック同期方式を修正する方法を修正するための方法を同期。この方法は、脱同期が同期する必要が効率的なコードブロックを、同期させることができます。
ThreadDomain21クラス

public class ThreadDomain21 {
    public synchronized void otherMethod()
    {
        System.out.println("----------run--otherMethod");
    }

    public void doLongTask()
    {
        synchronized (this)
        {
            for (int i = 0; i < 100; i++)
            {
                System.out.println("synchronized threadName = " +
                        Thread.currentThread().getName() + ", i = " + (i + 1));
                try
                {
                    Thread.sleep(5);
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}

MyThread21_0クラス

public class MyThread21_0 extends Thread{
    private ThreadDomain21 td;

    public MyThread21_0(ThreadDomain21 td)
    {
        this.td = td;
    }

    public void run()
    {
        td.doLongTask();
    }
}

MyThread21_1クラス

public class MyThread21_1 extends Thread{
    private ThreadDomain21 td;

    public MyThread21_1(ThreadDomain21 td)
    {
        this.td = td;
    }

    public void run()
    {
        td.otherMethod();
    }
}

mainメソッド、しばらくの間、睡眠は、MT0が最初に実行してみましょう。

public class MyThread21_main {
    public static void main(String[] args) throws Exception
    {
        ThreadDomain21 td = new ThreadDomain21();
        MyThread21_0 mt0 = new MyThread21_0(td);
        mt0.setName("A");
        MyThread21_1 mt1 = new MyThread21_1(td);
        mt1.setName("B");
        mt0.start();
        Thread.sleep(100);
        mt1.start();
    }
}

次のように出力結果があります

synchronized threadName = A, i = 1
synchronized threadName = A, i = 2
synchronized threadName = A, i = 3
synchronized threadName = A, i = 4
synchronized threadName = A, i = 5
synchronized threadName = A, i = 6
synchronized threadName = A, i = 7
synchronized threadName = A, i = 8
synchronized threadName = A, i = 9
synchronized threadName = A, i = 10
synchronized threadName = A, i = 11
synchronized threadName = A, i = 12
synchronized threadName = A, i = 13
synchronized threadName = A, i = 14
synchronized threadName = A, i = 15
synchronized threadName = A, i = 16
synchronized threadName = A, i = 17
synchronized threadName = A, i = 18
synchronized threadName = A, i = 19
synchronized threadName = A, i = 20
synchronized threadName = A, i = 21
synchronized threadName = A, i = 22
synchronized threadName = A, i = 23
......
synchronized threadName = A, i = 89
synchronized threadName = A, i = 90
synchronized threadName = A, i = 91
synchronized threadName = A, i = 92
synchronized threadName = A, i = 93
synchronized threadName = A, i = 94
synchronized threadName = A, i = 95
synchronized threadName = A, i = 96
synchronized threadName = A, i = 97
synchronized threadName = A, i = 98
synchronized threadName = A, i = 99
synchronized threadName = A, i = 100
----------run--otherMethod

次のように見ることができる、方法がブロックされdoLongTask otherMethodメソッドは、オブジェクト全体をロック同期記載の方法は、キーワードを除去同期otherMethod、出力結果であります

synchronized threadName = A, i = 1
synchronized threadName = A, i = 2
synchronized threadName = A, i = 3
synchronized threadName = A, i = 4
synchronized threadName = A, i = 5
synchronized threadName = A, i = 6
synchronized threadName = A, i = 7
synchronized threadName = A, i = 8
synchronized threadName = A, i = 9
synchronized threadName = A, i = 10
synchronized threadName = A, i = 11
synchronized threadName = A, i = 12
synchronized threadName = A, i = 13
synchronized threadName = A, i = 14
synchronized threadName = A, i = 15
synchronized threadName = A, i = 16
synchronized threadName = A, i = 17
synchronized threadName = A, i = 18
synchronized threadName = A, i = 19
synchronized threadName = A, i = 20
synchronized threadName = A, i = 21
----------run--otherMethod
......
synchronized threadName = A, i = 72
synchronized threadName = A, i = 73
synchronized threadName = A, i = 74
synchronized threadName = A, i = 75
synchronized threadName = A, i = 76
synchronized threadName = A, i = 77
synchronized threadName = A, i = 78
synchronized threadName = A, i = 79
synchronized threadName = A, i = 80
synchronized threadName = A, i = 81
synchronized threadName = A, i = 82
synchronized threadName = A, i = 83
synchronized threadName = A, i = 84
synchronized threadName = A, i = 85
synchronized threadName = A, i = 86
synchronized threadName = A, i = 87
synchronized threadName = A, i = 88
synchronized threadName = A, i = 89
synchronized threadName = A, i = 90
synchronized threadName = A, i = 91
synchronized threadName = A, i = 92
synchronized threadName = A, i = 93
synchronized threadName = A, i = 94
synchronized threadName = A, i = 95
synchronized threadName = A, i = 96
synchronized threadName = A, i = 97
synchronized threadName = A, i = 98
synchronized threadName = A, i = 99
synchronized threadName = A, i = 100

otherMethodメソッドは非同期に実行します。
以下の結論:
異なるメソッドは、オブジェクトが同期ロックされ、ミューテックスが同期されている修飾産生する、
一貫した同期ブロックおよび方法効果は、メソッドを同期。

同期(この非対象)

ThreadDomain22クラス

public class ThreadDomain22 {
    private String userNameParam;
    private String passwordParam;
    private String anyString = new String();

    public void setUserNamePassword(String userName, String password)
    {
        try
        {
            synchronized (anyString)
            {
                System.out.println("线程名称为:" + Thread.currentThread().getName() +
                        "在 " + new Date() + " 进入同步代码块");
                userNameParam = userName;
                Thread.sleep(3000);
                passwordParam = password;
                System.out.println("线程名称为:" + Thread.currentThread().getName() +
                        "在 " + new Date() + " 离开同步代码块");
            }
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}

MyThread22_0クラス

public class MyThread22_0 extends Thread{
    private ThreadDomain22 td;

    public MyThread22_0(ThreadDomain22 td)
    {
        this.td = td;
    }

    public void run()
    {
        td.setUserNamePassword("A", "AA");
    }
}

MyThread22_1クラス

public class MyThread22_1 extends Thread{
    private ThreadDomain22 td;

    public MyThread22_1(ThreadDomain22 td)
    {
        this.td = td;
    }

    public void run()
    {
        td.setUserNamePassword("B", "B");
    }
}

メイン

public class MyThread22_main{
    public static void main(String[] args)
    {
        ThreadDomain22 td = new ThreadDomain22();
        MyThread22_0 mt0 = new MyThread22_0(td);
        MyThread22_1 mt1 = new MyThread22_1(td);
        mt0.start();
        mt1.start();
    }
}

出力

线程名称为:Thread-0在 Tue Jul 02 14:51:16 CST 2019 进入同步代码块
线程名称为:Thread-0在 Tue Jul 02 14:51:19 CST 2019 离开同步代码块
线程名称为:Thread-1在 Tue Jul 02 14:51:19 CST 2019 进入同步代码块
线程名称为:Thread-1在 Tue Jul 02 14:51:22 CST 2019 离开同步代码块

同期(AnyString)は一貫して同期(本)の効果は、AnyStringグローバル変数は、非同期実行なり、複数のオブジェクトになり、内部の配置しようとした場合、オブジェクトからです。

例は見
ThreadDomain23クラスを

public class ThreadDomain23 {
    public void testMethod1(MyObject mo)
    {
        try
        {
            synchronized (mo)
            {
                System.out.println("testMethod1__getLock time = " +
                        new Date() + ", run ThreadName = " +
                        Thread.currentThread().getName());
                Thread.sleep(5000);
                System.out.println("testMethod1__releaseLock time = " +
                        new Date() + ", run ThreadName = " +
                        Thread.currentThread().getName());
            }
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}

MyObjectにクラス

public class MyObject {
    public synchronized void speedPrintString()
    {
        System.out.println("speedPrintString__getLock time = " +
                new Date() + ", run ThreadName = " +
                Thread.currentThread().getName());
        System.out.println("speedPrintString__releaseLock time = " +
                new Date() + ", run ThreadName = " +
                Thread.currentThread().getName());
    }
}

MyThread23_0クラス

public class MyThread23_0 extends Thread{
    private ThreadDomain23 td;
    private MyObject mo;

    public MyThread23_0(ThreadDomain23 td, MyObject mo)
    {
        this.td = td;
        this.mo = mo;
    }

    public void run()
    {
        td.testMethod1(mo);
    }
}

MyThread23_1クラス

public class MyThread23_1 extends Thread {
    private MyObject mo;

    public MyThread23_1(MyObject mo)
    {
        this.mo = mo;
    }

    public void run()
    {
        mo.speedPrintString();
    }
}

mainメソッド

public class MyThread23_main {
    public static void main(String[] args)
    {
        ThreadDomain23 td = new ThreadDomain23();
        MyObject mo = new MyObject();
        MyThread23_0 mt0 = new MyThread23_0(td, mo);
        MyThread23_1 mt1 = new MyThread23_1(mo);
        mt0.start();
        mt1.start();
    }
}

次のように出力結果があります

testMethod1__getLock time = Tue Jul 02 15:23:05 CST 2019, run ThreadName = Thread-0
testMethod1__releaseLock time = Tue Jul 02 15:23:10 CST 2019, run ThreadName = Thread-0
speedPrintString__getLock time = Tue Jul 02 15:23:10 CST 2019, run ThreadName = Thread-1
speedPrintString__releaseLock time = Tue Jul 02 15:23:10 CST 2019, run ThreadName = Thread-1

testMethod1方法はThreadDomain23がロックを取得した後に説明する方法をspeedPrintStringは常に実行され、syncronized方法のMOオブジェクトがブロックされ、メソッドを実行testMethod1はspeedPrintStringメソッドを実行されます。
これは、スレッドが、このメソッドを呼び出したときに、他のスレッドがブロックされています。
結論:
1.複数のスレッドが同時に(この非オブジェクト)同期実行{}シンクブロック同期効果として
2.一方同期効果が場合非同期同期方法の他のスレッドがこのオブジェクト

同期の静的メソッド

同期静的は現在のクラス、すなわちクラスのロックをロックすることができます。
ThreadDomain24クラス

public class ThreadDomain24 {
    public synchronized 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();
        }
    }

    public synchronized static void printB()
    {
        System.out.println("线程名称为:" + Thread.currentThread().getName() +
                "在" + System.currentTimeMillis() + "进入printB()方法");
        System.out.println("线程名称为:" + Thread.currentThread().getName() +
                "在" + System.currentTimeMillis() + "离开printB()方法");

    }

    public synchronized void printC()
    {
        System.out.println("线程名称为:" + Thread.currentThread().getName() +
                "在" + System.currentTimeMillis() + "进入printC()方法");
        System.out.println("线程名称为:" + Thread.currentThread().getName() +
                "在" + System.currentTimeMillis() + "离开printC()方法");
    }
}

MyThread24_0クラス、静的メソッド

public class MyThread24_0 extends Thread{
    public void run()
    {
        ThreadDomain24.printA();
    }
}

MyThread24_1クラス、静的メソッド

public class MyThread24_1 extends Thread {
    public void run()
    {
        ThreadDomain24.printB();
    }
}

MyThread24_2クラス、呼び出すメソッドはインスタンス化

public class MyThread24_2 extends Thread{
    private ThreadDomain24 td;

    public MyThread24_2(ThreadDomain24 td)
    {
        this.td = td;
    }

    public void run()
    {
        td.printC();
    }
}

mainメソッド

public class MyThread24_main {
    public static void main(String[] args)
    {
        ThreadDomain24 td = new ThreadDomain24();
        MyThread24_0 mt0 = new MyThread24_0();
        MyThread24_1 mt1 = new MyThread24_1();
        MyThread24_2 mt2 = new MyThread24_2(td);
        mt0.start();
        mt1.start();
        mt2.start();
    }
}

次のように出力結果があります

线程名称为:Thread-0在1562057924755进入printA()方法
线程名称为:Thread-2在1562057924755进入printC()方法
线程名称为:Thread-2在1562057924755离开printC()方法
线程名称为:Thread-0在1562057927755离开printA()方法
线程名称为:Thread-1在1562057927755进入printB()方法
线程名称为:Thread-1在1562057927755离开printB()方法

見ることができる、printA処理(ロックタイプ)とprintBプロセスが同期実行、printC法(オブジェクトロック)(タイプロック)非同期、printA方法および方法printBミューテックスは、printCクラスロックが影響されない行います。
結論:
静的メソッドは、2つの間でオブジェクトロック、干渉を保持するロック、非静的メソッドを保持しています。

おすすめ

転載: www.cnblogs.com/Java-Starter/p/11088977.html
おすすめ