Synchronous, asynchronous, class locks, the object lock

Synchronize

To perform a task, we need to rely on the completion of another task.
Standard program execution flow is synchronized only on a function execution is completed, the next function before they can begin, this is the dependency

asynchronous

To perform a task, do not rely on the completion of another task.
The concept of concurrency, just need to tell the need to do another task, it will go directly to the Executive

Object lock: Only when competing for the same target

  • synchronized modification 非静态方法, 代码块synchronized (this), synchronized (非this对象)thread synchronization code to be executed corresponding need to acquire the object lock

Lock method

An example of the first show did not lock, according to his output code can know, because we instantiate an object, and then open a thread to pass a parameter ain the past, to perform System.out.println("a arrived");he began to sleep 2s, this at the same time open another thread, the same call to the same method of the same object, passed bin the past, so there are the following results

public class main {

    public static void main(String[] args) throws IOException {
        person p = new person();
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.addstr("a");
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.addstr("b");
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();
        }
    }


class person{
    private int number = 0;
    public void addstr(String string) throws InterruptedException {
        if (string.equals("a")) {
            number = 100;
            System.out.println("a arrived");
            Thread.sleep(2000);
        }else {
            number = 200;
            System.out.println("b arrived");
            }
        System.out.println(string + " number=" + String.valueOf(number));
        }
    }

Output:

a arrived
b arrived
b number=200
a number=200

Minor changes to the addstrmethod plus lock, this time competing multi-threaded locking method of the same object, it is necessary in order to have to wait on a call to release the lock

class person{
    private int number = 0;
    synchronized public void addstr(String string) throws InterruptedException {
        if (string.equals("a")) {
            number = 100;
            System.out.println("a arrived");
            Thread.sleep(2000);
        }else {
            number = 200;
            System.out.println("b arrived");
            }
        System.out.println(string + " number=" + String.valueOf(number));
        }
    }

Another case is, a method of locking two classes, two different threads at the same time calls the object locked, this case, after the test, the output display, a second method for performing locked need to wait, that is 一个类内,使用一个锁,锁住一个或多个方法.

        person p = new person();
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.printA(string);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.printB(string);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();
        }
    }


class person{
    private int number = 0;
    synchronized public void printA(String string) throws InterruptedException {
        System.out.println("A 进入线程!");
        Thread.sleep(2000);
        System.out.println("A 离开线程!");
        }
    
    synchronized public void printB(String string) throws InterruptedException {
        System.out.println("B 进入线程!");
        System.out.println("B 离开线程!");
        }
}

Output:

A 进入线程!
A 离开线程!
B 进入线程!
B 离开线程!

synchronized (this)

The above class person again slight modification, we lock a block of code, multiple threads when the same 竞争同一个对象is 这个代码块needed to lock in accordance with the rules, a release, before the next use, the output supra

class person{
    private int number = 0;
    public void addstr(String string) throws InterruptedException {
        synchronized(this) {
        if (string.equals("a")) {
            number = 100;
            System.out.println("a arrived");
            Thread.sleep(2000);
        }else {
            number = 200;
            System.out.println("b arrived");
            }
        System.out.println(string + " number=" + String.valueOf(number));
        }
        }
    }

It should be noted it because multithreading competition rules only the contents of this block of code is the use of locks, which is the code block above, the following are not synchronized, modify the code, the synchronization code block above this, plus the following two outputs System.out.println(string + "来了");、System.out.println(string + " number=" + String.valueOf(number));, this time the output of the following two results. A first explained b来了output, because System.out.println(string + "来了");this one did not lock, so the first parameter with a atime of sleep, the second thread running to finish the output here b来了, it is here to stay, ranking a thread releases the lock, it can continue. As result, there are two, it is because another output statement System.out.println(string + " number=" + String.valueOf(number));unlocked, fully depending on who fast, who performs, or concurrent execution are possible

class person{
    private int number = 0;
    public void addstr(String string) throws InterruptedException {
        System.out.println(string + "来了");
        synchronized(this) {
        if (string.equals("a")) {
            number = 100;
            System.out.println("a arrived");
            Thread.sleep(2000);
        }else {
            number = 200;
            System.out.println("b arrived");
            }
        }
        System.out.println(string + " number=" + String.valueOf(number));
        }
    }

Output:

a来了
a arrived
b来了
b arrived
a number=100
b number=200

or

a来了
a arrived
b来了
b arrived
b number=200
a number=200

Same, synchronized (this) also exist in the same class, or using a lock with a plurality of code blocks, the code block is not the vertical sync

class person{
    public String son;
    public person(String son) {
        this.son = son;
    }
    private int number = 0;
    synchronized public void printA(String string) throws InterruptedException {
        System.out.println("A 进入线程!");
        Thread.sleep(2000);
        System.out.println("A 离开线程!");
        }
    
    public void printB(String string) throws InterruptedException {
        System.out.println("B ready!");
        synchronized (this) {
        System.out.println("B 进入线程!");
        System.out.println("B 离开线程!");
        }
    }

Output:

A 进入线程!
B ready!
A 离开线程!
B 进入线程!
B 离开线程!

synchronized (this non-target)

As long as an object with multiple threads access the object is locked, and the same, we need to lock in accordance with the rules, as the following example, although the examples of two different objects, but they are the same access a String object, there is competition. In fact, can be labeled as a locked object, any use of this thread is locked object, the equivalent of being marked, labeled thread execution place to synchronized statement, it is necessary to order, there is no concurrent get on

public static void main(String[] args) throws IOException {
        String string = "son";
        person p = new person(string);
        person p1 = new person(string);
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.addstr("a");
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p1.addstr("b");
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();
        }
    }


class person{
    public String son;
    public person(String son) {
        this.son = son;
    }
    private int number = 0;
    public void addstr(String string) throws InterruptedException {
        System.out.println(string + "来了");
        synchronized(son) {
        if (string.equals("a")) {
            number = 100;
            System.out.println("a arrived");
            Thread.sleep(2000);
        }else {
            number = 200;
            System.out.println("b arrived");
            }
        }
        System.out.println(string + " number=" + String.valueOf(number));
        }
    }

Locks

  • synchronized modification 静态方法, synchronized(类.class)the lock is the corresponding class, we need to obtain 类锁
    class lock is actually using the object lock, when loading a class file, create an instance of java.lang.Class class, a class when the lock is locked java. examples of class lang.Class

The following example is 对象锁different use person对象, i.e. the use of different lock with the person object

        String string = "son";
        person p = new person(string);
        person p1 = new person(string);
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.printA(string);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p1.printB(string);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();
        }
    }


class person{
    public String son;
    public person(String son) {
        this.son = son;
    }
    private int number = 0;
    synchronized public  void printA(String string) throws InterruptedException {
        System.out.println("A 进入线程!");
        Thread.sleep(2000);
        System.out.println("A 离开线程!");
        }
    
    synchronized public  void printB(String string) throws InterruptedException {
        System.out.println("B ready!");
        System.out.println("B 进入线程!");
        System.out.println("B 离开线程!");
    }
}

对象锁Output:

A 进入线程!
B ready!
B 进入线程!
B 离开线程!
A 离开线程!

Plus minor modifications static, let us use 类锁, even though instances of different objects, but the use of the same class, the output at this time is not the same, there is also used同一个类,使用一个锁锁住一个或多个方法、代码块

class person{
    public String son;
    public person(String son) {
        this.son = son;
    }
    private int number = 0;
    synchronized public static void printA(String string) throws InterruptedException {
        System.out.println("A 进入线程!");
        Thread.sleep(2000);
        System.out.println("A 离开线程!");
        }
    
    synchronized public static void printB(String string) throws InterruptedException {
        System.out.println("B ready!");
        System.out.println("B 进入线程!");
        System.out.println("B 离开线程!");
    }
}

Output:

A 进入线程!
A 离开线程!
B ready!
B 进入线程!
B 离开线程!

Again introducing a small experience point: 类锁and 对象锁mix
the same method using the above code is slightly modified, can be seen from the output, the lock of the object blocks of code, even for the same object, there is no mechanism to lock performed, illustrating类锁和对象锁混用的情况下,只有类锁有效,对象锁无效

this: the object represented by the current instance of the class

        person p = new person(string);
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.printA(string);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    p.printB(string);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();
        }
    }

class person{
    public String son;
    public person(String son) {
        this.son = son;
    }
    private int number = 0;
    synchronized public static void printA(String string) throws InterruptedException {
        System.out.println("A 进入线程!");
        Thread.sleep(2000);
        System.out.println("A 离开线程!");
        }
    
    public void printB(String string) throws InterruptedException {
        System.out.println("B ready!");
        synchronized (this) {
        System.out.println("B 进入线程!");
        System.out.println("B 离开线程!");
        }
    }
}

In order to prove that the order does not matter and locks, reverse the order to prove

class person{
    public String son;
    public person(String son) {
        this.son = son;
    }
    private int number = 0;
    
    public void printA(String string) throws InterruptedException {
        System.out.println("A ready!");
        synchronized (this) {
        System.out.println("A 进入线程!");
        Thread.sleep(2000);
        System.out.println("A 离开线程!");
        }
    }
    
    synchronized public static void printB(String string) throws InterruptedException {
        System.out.println("B 进入线程!");
        System.out.println("B 离开线程!");
        }
}

Output:

A ready!
A 进入线程!
B 进入线程!
B 离开线程!
A 离开线程!

Java class object lock and lock comprehensive analysis (multi-threaded synchronized keyword)

Published 118 original articles · won praise 14 · views 50000 +

Guess you like

Origin blog.csdn.net/github_38641765/article/details/86580439