Java multi-threading (III): Synchronized

Multi-thread safe

Dirty read: after multiple threads on the same object instance variables to modify access, leading to read data is modified.

Examples

ThreadDomain16 class

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 class

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 classes
start MyThread16_0 and MyThread16_1 thread

public class MyThread16_1 extends Thread {
    private ThreadDomain16 td;

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

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

}

main method

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();
    }
}

The output results are as follows

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

The output should ideally be a num = 100, b num = 200, the results of a num = 200.
We have to analyze operational processes, MyThread16_0 modify thread num is 100, then sleep for two seconds during MyThread16_0 sleep in, MyThread16_1 modify thread num 200. Lead num MyThread16_0 also becomes 200. Finally, the first output b num = 200, and then outputs a num = 200. She appeared dirty read.
To solve this problem is very simple, we () preceded by the synchronized keyword in addNum

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();
        }
    }

The output results are as follows

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

Sequential printing, synchronized modification of the method of forming the lock, which thread to execute a synchronized modification method which thread will first obtain a lock, other threads must wait until the thread releases the lock, waiting threads acquire the lock before implementation.

A lock object

同步情况Next, the following main method

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();
    }
}

operation result

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

CROSS print appears, b execution without waiting for the end of a described synchronized lock object, instead of locking methods. Here declares two ThreadDomain16 objects, so there are two objects lock, not "wait for the lock release" constraints.
So we put in front of addNum method to remove the synchronized keyword, 异步情况the lower
operating results as follows

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

You can see, there is no synchronized help, still avoiding the dirty read phenomenon. For each object instance variable num own possession. However, this solution need to declare more than one object is not recommended.

The method and the object synchronized lock

Now look at an example, there is a method of modifying synchronized, a further modified method is not synchronized
ThreadDomain17 class

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 class

public class MyThread17_0 extends Thread{
    private ThreadDomain17 td;

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

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

MyThread17_1 class

public class MyThread17_1 extends Thread{
    private ThreadDomain17 td;

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

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

main method

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();
    }
}

Results are as follows

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

You can see, the methodB non-synchronized method is invoked asynchronously.
The method of the run class MyThread17_1 into td.methodA ();
output the following

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

Thread to be executed in the synchronous method waits to perform again synchronized.
A thread holds the object lock ThreadDomain17, B thread non-synchronized method ThreadDomain17 objects can be invoked asynchronously;
A thread holds the object lock ThreadDomain17, B thread calls a synchronized method ThreadDomain17 object to wait;

the run method MyThread17_1 class back to td. methodB (); methodB method ThreadDomain17 the class with synchronized keyword, the output results are as follows

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

This is well understood, the first thread of execution to obtain synchronization lock, and so the thread must be finished, waiting threads to perform all operations are synchronized.

synchronized lock reentrant

reentrant lock is synchronized, when a thread lock to give the object, the object lock can apply again and obtain the object lock.
ThreadDomain18 class

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 class

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();
    }
    
}

The results are as follows

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

Description result, MyThread18 get in a locked case several times to object lock

Abnormal release lock

ThreadDomain19 class

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 class

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();
    }
}

The output results are as follows

进入 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)

As it is seen above, once the abnormal, the lock is automatically released. Thread-1 had just finished throwing an exception, this time Thread-1 release the lock, Thread-0 started execution.

Method synchronized block

ThreadDomain20 class

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 class

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();
    }

}

Results are as follows

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

Conclusion:
When A thread synchronized access methods block, B threads can still access the contents of a non-synchronized method blocks;
when the threads access the synchronized method A block, B block threads access the synchronized method will be blocked;

The method of synchronized blocks and synchronized method

consistent results synchronized keyword and a method for modifying method for modifying a block synchronized method. The method may be synchronized efficient code block, where de-synchronization need to be synchronized.
ThreadDomain21 class

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 class

public class MyThread21_0 extends Thread{
    private ThreadDomain21 td;

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

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

MyThread21_1 class

public class MyThread21_1 extends Thread{
    private ThreadDomain21 td;

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

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

main method, sleep for a while, let mt0 executed first.

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();
    }
}

The output results are as follows

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

Can be seen, the method is blocked doLongTask otherMethod method described synchronized lock the entire object, the method otherMethod synchronized keyword removed, the output results are as follows

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 method asynchronously executed.
The following conclusions:
different methods produce modified mutex is synchronized, the object is locked synchronized;
consistent synchronized blocks and method effect synchronized method;

synchronized (this non-target)

ThreadDomain22 class

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 class

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 class

public class MyThread22_1 extends Thread{
    private ThreadDomain22 td;

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

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

main

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();
    }
}

Output

线程名称为: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 离开同步代码块

synchronized (AnyString) consistent and synchronized (this) effect, AnyString as a global variable is an object, if placed inside try, it becomes a plurality of objects, become asynchronous execution.

An example look
ThreadDomain23 class

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 class

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 class

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 class

public class MyThread23_1 extends Thread {
    private MyObject mo;

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

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

main method

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();
    }
}

The output results are as follows

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

speedPrintString method is always executed after testMethod1 method described ThreadDomain23 get a lock, syncronized method mo object is blocked, testMethod1 executing the method will be performed speedPrintString method.
That is, when a thread calls this method, other threads blocked.
Conclusion:
1. When a plurality of threads simultaneously executed synchronized (this non-object) {} as a sync block synchronization effect
2. While synchronization effect when other threads of non-synchronized synchronization method this object

synchronized static method

synchronized static can lock the current class, i.e. the class locks.
ThreadDomain24 class

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 class, static methods

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

MyThread24_1 class, static methods

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

MyThread24_2 class, calling methods instantiate

public class MyThread24_2 extends Thread{
    private ThreadDomain24 td;

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

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

main method

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();
    }
}

The output results are as follows

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

Can be seen, printA process (lock type) and printB process (lock type) synchronous execution, printC method (Object lock) performed asynchronously, printA methods and methods printB mutex, printC class lock is not affected.
Conclusion: The
static method holds Locks, non-static method of holding the object lock, interference between the two.

Guess you like

Origin www.cnblogs.com/Java-Starter/p/11088977.html