synchronized and reentrantlock implement multi-thread synchronization locking

Table of Contents

Multithreading:

Advantages of multithreading:

Disadvantages of multithreading:

Solution: Multi-thread synchronization

Locking method one: synchronized()

Inherit Thread()

Implement the Runnable interface

Locking method two: reentrantLock implements locking


Multi-threading:

In an application, there are multiple threads, and different threads can perform tasks in parallel.

Multi-threading advantages:
  • Improve program processing capabilities

    For example: anti-virus software

    • Trash removal 1 minute.

    • Virus detection takes 1 minute.

  • Improve cpu utilization

    • Split large tasks (task manager)

Disadvantages of multi-threading:
  • The more threads, the more memory will be occupied (solved by hardware upgrade)

  • When multiple threads access shared resources simultaneously, thread safety issues may arise.

Solution: Multi-thread Synchronization

Locking: Only one thread can access shared resources at a time

Locking method one: synchronized()
Inherit Thread()
  • Decorate code blocks

    synchronized modified code block

    synchronized(synchronized object/lock){

    }

    Synchronization object: One object corresponding to multiple threads must be used to record whether any thread enters the synchronization code block; the synchronization object can be an object of any class in Java.

    When there are multiple objects corresponding to synochronized

    It is equivalent to creating multiple locks, but security problems will still occur. But you can create a public synchronization object to occupy the thread.

    public class TicketThreadText {
        public static void main(String[] args) {
            TicketThread t1=new TicketThread();
            t1.setName("Window 1");
            TicketThread t2=new TicketThread();
            t2.setName("Window 2");
            t1.start();
            t2.start();
        }
    }
    public class TicketThread extends Thread{
        static int t=10;//Unable to solve the problem, the run method may be entered at the same time, causing t to be entered as 10.
        static byte[] bytes=new byte[0];//The lock has no special meaning only to achieve synchronization of multiple objects//When the second object references bytes, it will be locked and wait for the first bytes to be processed
        /*synchronized modified code block
    ?
        Synchronization object: One object corresponding to multiple threads must be used to record whether any thread has entered the synchronization code block;
        A synchronization object can be an object of any class in Java.
    ?
        synchronized(synchronized object){
    ?
        }*/
        @Override
        public void run() {
            while(true){
                synchronized(bytes) {
                    if (t > 0) {
                        System.out.println(Thread.currentThread().getName() + "Bought Chapter" + t + "ticket");
                        t--;
                    } else {
                        break;
                    }
                }
            }
        }
    }
  • Modification method

    synchronized modification method, the synchronization object will have the default one.

    If the modified method is a non-static method, then the synchronization object is this.

    If the modified method is a static method, then the synchronization object is the Class object of the current class.

    Class object of the current class: When a class is loaded into memory, a unique Class object will be created for this class.

    public class SynchronizedForTicketThread extends Thread{
        static int t=10;
    ?
        @Override
        public void run() {
            thread();
        }
    ?
        static public synchronized void thread()
        {
            while(true)
            {
                if(t<=0)
                {
                    break;
                }
                else{
                    System.out.println(Thread.currentThread().getName() + "bought the first" + t + "chapter ticket");
                    t--;
                }
            }
        }
    }
    public class TicketThreadText {
        public static void main(String[] args) {
            SynchronizedForTicketThread t1=new SynchronizedForTicketThread();
            t1.setName("Window 1");
            SynchronizedForTicketThread t2=new SynchronizedForTicketThread();
            t2.setName("Window 2");
            t1.start();z
            t2.start();
        }
    }
    ?
Implement Runnable interface

No need to use static methods to have only one task object

So just use synchronized modification directly

  • Decorate code blocks

public class RunnableForTicketThread implements Runnable {
     int t=10;
    @Override
    public void run() {
        while(true)
        {
            synchronized (this) {
                if (t > 0) {
                    System.out.println(Thread.currentThread().getName() + "Out of Chapter" + t + "Chapter Ticket");
                    t--;
                } else {
                    break;
                }
            }
        }
    }
}
public class RunnableTxet {
    public static void main(String[] args) {
        RunnableForTicketThread runnableForTicketThread=new RunnableForTicketThread();
        Thread thread1=new Thread(runnableForTicketThread,"Window One");
        Thread thread2=new Thread(runnableForTicketThread,"Window 2");
        thread1.start();
        thread2.start();
    }
}
?
  • Modification method

    public class SynchronizedRunnableForTicket implements Runnable{
        int t=10;
        @Override
        public void run() {
            thread();
        }
        public synchronized void thread()
        {
            while(true) {
                if(t>0) {
                  System.out.println(Thread.currentThread().getName() + "Bought the first ticket" + t + "ticket");
                  t--;
                }
                else {break;}
            }
        }
    }
    public class RunnableTxet {
        public static void main(String[] args) {
            SynchronizedRunnableForTicket synchronizedRunnableForTicket=new SynchronizedRunnableForTicket();
            Thread thread1=new Thread(synchronizedRunnableForTicket,"Window One");
            Thread thread2=new Thread(synchronizedRunnableForTicket,"Window Two");
            thread1.start();
            thread2.start();
        }
    }

The result of running the above program is:

Locking method two: reentrantLock implements locking
public class ReentrantLookForTicketRunnable implements Runnable{
    int t=10;
    ReentrantLock reentrantLock=new ReentrantLock();
    @Override
    public void run() {
        while(t>1) {
            reentrantLock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + "Bought the first ticket" + t + "ticket");
                t--;
            } finally {
                reentrantLock.unlock();
            }
        }
    }
}
public class ReentrantLookText {
    public static void main(String[] args) {
        ReentrantLookForTicketRunnable reentrantLookForTicketRunnable = new ReentrantLookForTicketRunnable();
        Thread thread1 = new Thread(reentrantLookForTicketRunnable, "Window One");
        Thread thread2 = new Thread(reentrantLookForTicketRunnable, "Window Two");
        thread1.start();
        thread2.start();
    }
}
?

Similarity: they all implement the locking function

difference:

  1. Synchronized is a keyword and ReentrantLock is a class

  2. Synchronized modifies code blocks and methods, ReentrantLock can only modify code blocks

  3. Synchronized can implicitly add and release locks, and can automatically release locks if an exception occurs during operation. ReentrantLock needs to manually add and release locks. It is recommended to release the lock in the finally code block.