JUC concurrent programming

Posted by metalenchantment on Fri, 10 Dec 2021 13:52:01 +0100

Synchronous and asynchronous:

  • You need to wait for the result to return before you can continue running, which is synchronization
  • It is asynchronous to continue running without waiting for the result to return

start() and run()

difference:

  • Call start() to start a new thread. Stealing the run() method is a call to an ordinary method and will not create a new thread.
  • Calling the start() method will execute the code in the run() method.
  • The start() method cannot be called more than once, and an IllegalThreadsStateException will occur if it is called more than once.

sleep() and yield()

sleep(): put the thread to sleep

  • Calling sleep will make the current thread enter the Timed Waiting state (blocking) from Running.

  • Other threads can use the interrupt() method to interrupt the sleeping thread, and the sleep method will throw an InterruptedException.

  • After sleep, the thread may not be executed immediately. It will first enter the ready state and wait for the cpu to allocate time slices.

  • The sleep() method cannot throw an exception. It can only catch an exception

  • It is recommended to use the sleep of TimeUnit (after jdk1.5) instead of the sleep of Thread to obtain better readability.

    //All sleep for 1 second
    TimeUnit.SECONDS.sleep(1);
    Thread.sleep(1000);
    

yield(): put the running thread into a ready state

  • Call thread Yield () will enable the current thread to enter the Runnable ready state from Running (running state), then schedule other threads.
  • The specific implementation depends on the task scheduler of the operating system

Differences between the two:

  • sleep(): the time slice occupied by the current thread will be released. The cpu will not re allocate the time slice until the sleep time is over or interrupted by interrupt(), waiting for the cpu to call again.
  • yield(): it will also give up the time slice, wait for the cpu to re allocate the time slice, and the cpu will reschedule, but there is no sleep time.

thread priority

After the thread priority, the task scheduler will be prompted to schedule the thread first, but it is only a prompt. The final task scheduling situation has to be determined by the scheduler. For example, when the cpu is busy, the thread with high priority will get more time slices. When the cpu is idle, the priority will even be ignored, resulting in failure.

Set priority:

 t1.setPriority(n);
 //n[ 1 , 10 ]
 //1: Minimum priority
 //5: Default priority
 //10: Maximum priority

join(): let the current thread wait for another thread to finish executing before continuing to execute the current thread

Case:

    static int r = 0;
    public static void main(String[] args) throws InterruptedException {
        test1();
    }
    private static void test1() throws InterruptedException {
        log.debug("start");
        Thread t1 = new Thread(() -> {
            log.debug("start");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.debug("end");
            r = 10;
        });
        t1.start();
//        t1.join();
        log.debug("The result is:{}", r);
        log.debug("end");
    }
The current case execution result is **r=0** instead of **r=10**

analysis:

Because the main thread and thread t1 execute in parallel, thread t1 needs 1 second to calculate r=10
The main thread prints the result of R at the beginning, so it can only print r=0.

Solution:
If you want the final result to be r=10, you need to make the main thread wait for t1 thread to execute, and then the main thread will print the final result (asynchronous to synchronous). That is, the join() method is called.

Join (milliseconds): the current thread waits for another thread

Explanation: the current thread waits for another thread to execute. Unlike the join() method, which has no parameters, the join() method makes the current thread wait for another thread to finish. The join(500) indicates that the current thread waits for another thread for 500 milliseconds at most. If another thread fails to complete execution within 5 seconds, it will no longer wait and continue to execute the current thread.

static int r1 = 0;
    public static void main(String[] args) throws InterruptedException {
        test3();
    }

    public static void test3() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            r1 = 10;
        });
        long start = System.currentTimeMillis();
        t1.start();
        // The end of thread execution will lead to the end of the join
        t1.join(500);
        long end = System.currentTimeMillis();
        log.debug("r1: {} r2: {} cost: {}", r1, end - start);
    }
The current case execution result is **r=0** instead of **r=10**

Topics: Java Back-end JUC