java Concurrent Programming (challenge of concurrent programming)

Context switching

Single core processors also support multi-threaded code execution. The CPU allocates CPU time slices to each thread to realize the mechanism of multi-threaded execution. The time slice is the time allocated by the CPU to each thread. Because the time slice is very short, the CPU keeps switching threads for execution, which makes us feel that multiple threads execute at the same time. The time slice is generally tens of milliseconds (ms). The CPU circularly executes tasks through the time slice allocation algorithm. After the current task executes a time slice, it will switch to the next task. However, the status of the previous task will be saved before switching, so that the status of this task can be loaded again when switching back to this task next time. Therefore, the process from saving to reloading a task is a context switch.

For example, we are reading a book, but your mother told you to eat at this time. Do you have to put down your book and eat (I tried not to listen to my mother and have been scolded for a long time, don't try!). At this time, you have to remember the page and line of the book you read. When you come back from dinner, go on reading. But if you read again at this time, will it affect your concentration in reading because you have just finished dinner. This is context switching. Similarly, context switching will affect the execution speed of multithreading.

Example code test:

public class ConcurrencyTest {

    private static final long count = 100000001;

    // Concurrent execution
    private static void concurrency() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                int a = 0;
                for (int i = 0; i < count; i++) {
                    a+=5;
                }
            }
        });
        thread.start();
        int b = 0;
        for (long i = 0; i < count; i++) {
            b--;
        }
        long time = System.currentTimeMillis() - start;
        thread.join();
        System.out.println("concurrency : "+time+"ms,b = "+b);
    }

    // Serial execution
    private static void serial(){
        long start = System.currentTimeMillis();
        int a = 0;
        for (int i = 0; i < count; i++) {
            a+=5;
        }
        int b = 0;
        for (long i = 0; i < count; i++) {
            b--;
        }
        long time = System.currentTimeMillis() - start;
        System.out.println("concurrency : "+time+"ms,b = "+b+",a = "+a);
    }
    public static void main(String[] args) throws InterruptedException {
        concurrency();
        serial();
    }
}


This is serial and parallel execution data. Different computers and different configurations may get different data. Why is serial code faster than concurrent code when the amount of data is small? Because java programs executed concurrently have the overhead of thread creation and context switching. However, it can be concluded that code executed concurrently is not necessarily faster than code executed serially.

Method for reducing context switching

1. Lock free concurrent programming
2. CAS algorithm
3. Use minimal threads
4. Use CO process

deadlock

Deadlock code demonstration

public class DeadLockDemo {

    private static String A = "a";
    private static String B = "b";

    public static void main(String[] args) {
        new DeadLockDemo().deadLock();
    }
    private void deadLock(){
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (A){
                    try{
                        Thread.sleep(2000);
                    } catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    synchronized (B){
                        System.out.println("123");
                    }
                }
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (B){
                   synchronized (A){
                       System.out.println("234");
                   }
                }
            }
        });
        t1.start();
        t2.start();
    }
}

Challenges of resource constraints

What are resource constraints?

Resource limitation means that the execution speed of the program is limited by computer hardware resources or software resources during concurrent programming.
Example: for example, the bandwidth of the server is only 2Mb/s, and the download speed of a resource is 1Mb/s per second. The system starts 10 threads to download resources, and the download speed will not become 10Mb/s. therefore, the limitations of these resources should be considered during concurrent programming. Hardware resource limitations include bandwidth upload / download speed, hard disk read-write speed and CPU processing speed. Software resource limits include the number of database connections and socket connections.

Problems caused by resource constraints

In concurrent programming, the principle of speeding up code execution is to turn the serial execution part of the code into concurrent execution. However, if a serial code is executed concurrently, because it is limited by resources, it is still executing serially. At this time, the program will not speed up execution, but will be slower, because it increases the time of context switching and resource scheduling. For example, a java program needs to call CPU, memory and network devices. In a word, it uses multithreading to download multiple targets at the same time, and then the computer is limited by network speed, computer storage speed and computer CPU processing speed. At this time, it often takes a multithreaded task that cannot be completed for several hours, but if it is single threaded, The task can be completed in more than an hour.

How to effectively solve the problem of resource constraints

Hardware resources: now consider using cluster to execute programs in parallel, because the resources of a single machine are limited.
Software resources: consider using resource pools to reuse resources. For example, use the connection pool to reuse the database and Socket connections, or establish only one connection when calling the other party's webservice interface to obtain data.

How to make the program execute faster under resource constraints? The method is to adjust the concurrency of programs according to different resource constraints. For example, downloading files depends on two resources - bandwidth and hard disk read-write speed. When there are database operations, the number of database connections is involved. If the execution of SQL statements is very fast and the number of threads is much larger than the number of database connections, some threads will be blocked and wait for database connections.

Keywords: Java Back-end

Added by GarroteYou on Sat, 01 Jan 2022 11:04:31 +0200