JUC high concurrency programming

Keywords: Java JUC

JUC overview

1.1 introduction to JUC

  • java.util.concurrent package is an API for concurrent programming
  • There are three packages related to JUC: java.util.concurrent, java.util.concurrent.atomic, and java.util.concurrent.locks

1.2 processes and threads

  • Process: a running application in the system; A program is a process; The smallest unit of process operating system resource allocation
  • Thread: the basic unit in which the system allocates processor time resources; A unit execution flow that executes independently within a process. Thread is the smallest unit of program execution

1.3 thread status

1.3.1 thread status enumeration

1.3.2 differences between wait and sleep

  • sleep is a static method of Thread. wait is an Object method that can be called by any Object instance.
  • sleep does not release the lock, nor does it need to occupy the lock. wait releases the lock, but it is called on the premise that the current thread occupies the lock (that is, the code should be in synchronized).
  • Can be interrupted by the interrupted method.

1.4 concurrency and parallelism

1.4.1 serial mode

  • All tasks are performed in order. Only one task can be obtained at a time. Only after completing this task can the next task be executed.

1.4.2 parallel mode

  • Multiple tasks are performed simultaneously. You can get multiple tasks at the same time and perform them at the same time.

1.4.3 concurrency

  • Concurrency: multiple threads are accessing the same resource at the same time, and multiple threads are connected to one point. For example: Spring Festival transportation ticket grabbing e-commerce spike
  • Parallel: multiple tasks are executed together and then summarized. For example: soak instant noodles, boil water in an electric kettle, tear the seasoning and pour it into the bucket

1.4.5 summary (key points)

1.5 tube side

  • Manage shared variables and their operations so that they support concurrent access. That is, manage the member variables and member methods of the class to make the class thread safe.

1.6 user threads and daemon threads

  • User thread (user-defined thread): the main thread ends, the user thread is still executing, and the JVM survives. You can set the thread as a daemon through the setDaemon(true) method of the thread
  • Daemon thread (garbage collection): there are no user threads, they are all daemon threads, and the JVM ends

2. Lock interface

2.1 Synchronized keyword

2.1.1 synchronized overview

synchronized{
	...
}

Is a keyword in java and a synchronization lock

  1. Modify the code block. The modified code block is a synchronous code block. The scope of action is within {}. The action object is the object calling this code block
  2. The modified method is a synchronous method, the scope of action is the whole method, and the action object is the object calling this method
  • Although you can use synchronized to define a method, synchronized is not part of the method definition, so the synchronized keyword cannot be inherited. If the synchronized keyword is used in a method of the parent class and the method is overridden in the subclass, the method in the subclass is asynchronous by default, and the synchronized keyword must be explicitly added to the method of the subclass.
  • Of course, you can also call the corresponding method in the parent class in the subclass, so that although the subclass method is not synchronous, the subclass calls the synchronization method of the parent class, so the subclass to the method is also equivalent to synchronization.
  1. Modifies a static method. The scope of action is the entire static method, and the action object is all objects of this class
  2. Modify a class. The scope of action is the bracketed part after synchronized. The object of action is all objects of this class

2.1.2 simulated ticket selling

class Ticket {
    // Number of votes
    private int number = 100;

    // Selling tickets
    public synchronized void sale() {
        if (number > 0) {
            System.out.println(Thread.currentThread().getName() + "Sell No:" + (number--) + " be left over:" + number);
        }
    }

}

public class TicketMain {
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i = 0; i<100; i++){
                    ticket.sale();
                }
            }
        }, "AA").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i = 0; i<100; i++){
                    ticket.sale();
                }
            }
        }, "BB").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i = 0; i<100; i++){
                    ticket.sale();
                }
            }
        }, "CC").start();
    }
}

2.1.3 multi thread programming steps (Part I)

  1. Create resource classes, create properties and operation methods
  2. Create a method that calls a resource class with multiple threads

2.2 Lock interface

  • It belongs to the java.util.concurrent.locks package. It provides a framework interface and class for locks and waiting conditions, which is different from the built-in synchronization and monitor
  • The Lock implementation provides a wider range of locking operations than can be obtained using synchronized methods and statements

2.2.1 difference between synchronized and Lock

  • synchronized is the keyword for Java. At the JVM level, Lock is a class
  • The synchronized exception will automatically release the Lock, so it will not cause deadlock. If an exception occurs to Lock, you need to actively release the Lock, otherwise a deadlock will occur.
  • synchronized cannot respond to interrupts, and the waiting thread will wait all the time. Lock allows threads waiting for locks to respond to interrupts.
  • synchronized cannot get the state of the lock. Lock can know whether the lock was successfully acquired.
  • Lock can improve the efficiency of reading operations by multiple threads.

The competitive resources are not intense, and the performance of the two is equivalent. When the competitive resources are intense (a large number of threads compete at the same time), the Lock performance is much better than synchronized.

Lock lock simulation ticket selling

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Ticket {
    // Number of votes
    private int number = 100;

    Lock lock = new ReentrantLock();

    // Selling tickets
    public synchronized void sale() {
        try{
            // Acquire lock
            lock.lock();
            if (number > 0) {
                System.out.println(Thread.currentThread().getName() + "Sell No:" + (number--) + " be left over:" + number);
            }
        }finally {
            // Release lock
            lock.unlock();
        }
    }

}

public class LTicketMain {

    public static void main(String[] args) {
        Ticket ticket = new Ticket();

        new Thread(()->{
            for(int i = 0; i<100; i++){
                ticket.sale();
            }
        }, "AA").start();

        new Thread(()->{
            for(int i = 0; i<100; i++){
                ticket.sale();
            }
        }, "BB").start();

        new Thread(()->{
            for(int i = 0; i<100; i++){
                ticket.sale();
            }
        }, "CC").start();
    }
}

details

  • When a thread calls the start() method, it may not be created immediately. The specific time of creation is determined by the operating system. When the operating system is idle, threads will be created immediately. If it is not idle, threads will be created later.

2.3 four ways to create threads

  • Inherit Thread class
  • Implement Runnable interface
  • Using the Callable interface
  • Is a thread pool

3. Inter thread communication

4. Customized communication between threads

5. Thread safety of collections

5.1 collection thread unsafe demonstration

5.2 ArrayList solution

Vector

List<String> list= new Vector<>();
  • The synchronized keyword is added to all methods to achieve thread safety

Collections

List<String> list= Collections.synchronizedList(new ArrayList<>());

CopyOnWriteArrayList

List<String> list = new CopyOnWriteArrayList<>();

Underlying principle

  • Concurrent reading and independent writing: when reading, you read the original array. When writing, you will copy the new array, operate on the new array, and then merge with the original array. When reading again, you will read the merged array.

5.3 HashSet thread unsafe

  • Using CopyOnWriteArraySet

5.4 unsafe HashMap thread

  • ConcurrentHashMap

Posted by Imothep on Tue, 05 Oct 2021 10:17:01 -0700