The Java thread synchronization with lock

Why simultaneous processing threads?

What is sync?
Refers to all sync threads are not executing the method enters together, but in order to come one by one.
Example: multiple threads synchronization ticket

class MyThread implements Runnable {
    private int tickte = 10;

    @Override
    public void run() {
        while (tickte > 0) {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "还剩" + this.tickte + "张票");
            this.tickte--;
        }
    }

}

class Test{
    public static void main(String[] args)throws InterruptedException {
       MyThread myThread=new MyThread();
       Thread thread1=new Thread(myThread,"线程A");
        Thread thread2=new Thread(myThread,"线程B");
        Thread thread3=new Thread(myThread,"线程C");
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

The result:
Here Insert Picture Description
observe the operation of the code above, we find that the number of votes actually appeared negative. Why would this look like? Because we created three threads at the same time selling tickets, they will also enter the run (method), and buy a ticket, if that now when there are 2 tickets, but because three threads simultaneously sell a ticket, thread A originally we only sell a ticket a ticket, but the thread B and C have entered the thread while loop, but also that there are two tickets continue to sell, this operation is called out of sync operation . The only advantage is that processing speed is not synchronized block (multi-threaded execution).

Sync

synchronized deal with synchronization issues

To achieve synchronization process, we can lock the operation, using the keyword synchronized to deal with. There are two modes using synchronized keyword process: the synchronization code block synchronization method.

Using the sync block

If the synchronization code block must be used to set the object to be locked, you can lock the general objects: the this
Example:

class MyThread implements Runnable {
    private int tickte = 10;//一共10张票

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
        //在同一时刻,只允许一个线程进入代码块处理
            synchronized (this) {
                if (tickte > 0) {
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }//模拟网络延迟
                    System.out.println(Thread.currentThread().getName() + "还剩" + this.tickte + "张票");
                    this.tickte--;
                }
            }
        }
    }
}

class Test{
    public static void main(String[] args)throws InterruptedException {
       MyThread myThread=new MyThread();
       Thread thread1=new Thread(myThread,"线程A");
        Thread thread2=new Thread(myThread,"线程B");
        Thread thread3=new Thread(myThread,"线程C");
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

operation result:
Here Insert Picture Description

Use synchronization method

example:

class MyThread implements Runnable {
    private int tickte = 10;

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            sale();
        }
    }
    
    //同步方法
    public synchronized void sale(){
        if (tickte > 0) {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "还剩" + this.tickte + "张票");
            this.tickte--;
        }
    }
}

class Test{
    public static void main(String[] args)throws InterruptedException {
       MyThread myThread=new MyThread();
       Thread thread1=new Thread(myThread,"线程A");
        Thread thread2=new Thread(myThread,"线程B");
        Thread thread3=new Thread(myThread,"线程C");
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

Although synchronization can ensure data integrity (thread-safe operation), but the speed of its implementation will be very slow
Note: After reading the two lock operation, you must have a question why only locking operation is ---- not unlock does it work? In fact, it has an implicit unlock operation, that is, after executing code inside the lock, it will automatically unlock.

synchronized multi-object lock

Examples: synchronized multi-object lock

class Sync{
    //锁的是当前对象this
    public synchronized void test(){
        System.out.println("test方法开始,当前线程为 "+Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("test方法结束,当前线程为 "+Thread.currentThread().getName());
    }
}
class MyThread implements Runnable {

    @Override
    public void run() {
       Sync sync=new Sync();
       sync.test();
    }
}
class Test{
    public static void main(String[] args)throws InterruptedException {
      MyThread myThread=new MyThread();
       Thread thread1=new Thread(myThread);
        Thread thread2=new Thread(myThread);
        Thread thread3=new Thread(myThread);
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

The result:
Here Insert Picture Description
observe the above code, we found no lock, three threads simultaneously run test () method. Because each process running run () method is going to be a new Sync new object, synchronized (this) as well as non-static synchronized method can only prevent multiple threads simultaneously perform a synchronization code section of the same object. That is synchronized locked in parentheses objects rather than code. For non-static synchronized method, the lock is the object itself that is this.
That how to solve the above problem?

Lock the same object

class Sync{
    //锁的是当前对象this
    public synchronized void test(){
        System.out.println("test方法开始,当前线程为 "+Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("test方法结束,当前线程为 "+Thread.currentThread().getName());
    }
}
class MyThread implements Runnable {
    private Sync sync;

    public MyThread(Sync sync){
        this.sync=sync;
    }

    @Override
    public void run() {
       sync.test();
    }
}
class Test{
    public static void main(String[] args)throws InterruptedException {
      MyThread myThread=new MyThread(new Sync());
       Thread thread1=new Thread(myThread);
        Thread thread2=new Thread(myThread);
        Thread thread3=new Thread(myThread);
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

operation result
Here Insert Picture Description

Global lock (lock code segment)

Global lock in two ways: using a static class synchronization method Class object and the lock in the code block.

Static synchronized method class
 synchronized与static一起使用,方法中无法使用this,所以它锁的不是this,而是类的Class对象,所以,static synchronized方法也相当于全局锁,相当于锁住了代码段。
class Sync{
    public static synchronized void test(){
        System.out.println("test方法开始,当前线程为 "+Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("test方法结束,当前线程为 "+Thread.currentThread().getName());
    }
}
class MyThread implements Runnable {

    @Override
    public void run() {
        Sync sync=new Sync();
       sync.test();
    }
}
class Test{
    public static void main(String[] args)throws InterruptedException {
      MyThread myThread=new MyThread();
       Thread thread1=new Thread(myThread);
        Thread thread2=new Thread(myThread);
        Thread thread3=new Thread(myThread);
        thread1.start();
        thread2.start();
        thread3.start();
    }
}
Lock this Class object code block
   synchronized (类名称.Class){},这种全局锁,锁的是类而不是this

class Sync{
    public  void test() {
    //锁的是类而不是this
        synchronized (Sync.class) {
            System.out.println("test方法开始,当前线程为 " + Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("test方法结束,当前线程为 " + Thread.currentThread().getName());
        }
    }
}
class MyThread implements Runnable {

    @Override
    public void run() {
        Sync sync=new Sync();
       sync.test();
    }
}
class Test{
    public static void main(String[] args)throws InterruptedException {
      MyThread myThread=new MyThread();
       Thread thread1=new Thread(myThread);
        Thread thread2=new Thread(myThread);
        Thread thread3=new Thread(myThread);
        thread1.start();
        thread2.start();
        thread3.start();
    }
}
Published 87 original articles · won praise 73 · views 10000 +

Guess you like

Origin blog.csdn.net/HL_HLHL/article/details/84204295