[Learning JAVA from scratch | Article 38] Applying multithreading

Table of contents

Foreword:

Implementation of multithreading:

Common member methods of Thread:

Summarize:


Foreword:

           The introduction of multi-threading is not only a technical means to improve computer processing power, but also an inevitable choice to meet the efficiency and performance requirements of the current era. In this article, we will deeply discuss the application and practice of multithreading, help readers better understand and apply multithreading technology, improve the processing ability of computers, and meet the world of challenges. "

Implementation of multithreading:

        1. Inherit the Thread class : You can create a class and inherit the Thread class, then override the run() method, and define the tasks to be performed by the thread in the run() method. By creating an instance of this class and calling the start() method, a new thread can be started to execute the tasks in the run() method.

Sample code:

class MyThread extends Thread {
    public void run() {
        // 定义线程要执行的任务
        System.out.println("线程执行任务");
    }
}

public class MainClass {
    public static void main(String[] args) {
        // 创建线程并启动
        MyThread thread = new MyThread();
        thread.start();
    }
}

        2. Implement the Runnable interface : You can create a class that implements the Runnable interface, then implement the run() method, and then create a new thread by creating a Thread object and passing the Runnable object as a parameter to the Thread constructor.

Sample code:

class MyRunnable implements Runnable {
    public void run() {
        // 定义线程要执行的任务
        System.out.println("线程执行任务");
    }
}

public class MainClass {
    public static void main(String[] args) {
        // 创建线程并启动
        MyRunnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start();
    }
}

        3. Use the Executor framework : Java provides the Executor framework, which is a way of advanced thread management. With Executor, you can use the thread pool to manage and execute multiple thread tasks, providing better thread control and resource management.

Sample code:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MainClass {
    public static void main(String[] args) {
        // 创建线程池
        ExecutorService executor = Executors.newFixedThreadPool(5);

        // 提交任务
        executor.execute(new Runnable(){
            public void run() {
                // 定义线程要执行的任务
                System.out.println("线程执行任务");
            }
        });

        // 关闭线程池
        executor.shutdown();
    }
}

         4. Realize by using Callable and Future interfaces : When you need to get the return result after the thread is executed, you can use Callable and Future interfaces to implement multi-threading. Callable is a task with a return result, you can execute the task and return the result through the call() method. Future represents an asynchronously executed task, and the return result of the task can be obtained through the get() method.

The advantage of this method is that: the execution results of multi-threads can be obtained 

Sample code:



class MyCallable implements Callable<Integer> {
    public Integer call() throws Exception {
        // 定义线程要执行的任务,并返回结果
        return 42;
    }
}

public class MainClass {
    public static void main(String[] args) {
        // 创建线程池
        ExecutorService executor = Executors.newSingleThreadExecutor();

        // 提交Callable任务
        Future<Integer> future = executor.submit(new MyCallable());

        // 等待并获取结果
        try {
            Integer result = future.get();
            System.out.println("线程执行任务的结果为: " + result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        // 关闭线程池
        executor.shutdown();
    }
}

Common member methods of Thread:

  • start() : Start the thread, make the thread enter the runnable state, and the specific execution is scheduled by the operating system.
  • run() : The task code executed by the thread, usually by overriding this method to define the logic to be executed by the thread.
  • sleep(long millis) : Let the current thread sleep for the specified number of milliseconds, suspending the execution of the thread.
  • join() : Wait for the thread execution to complete, that is, wait for the thread to terminate.
  • yield() : Suspends the currently executing thread and allows other threads to execute.
  • isAlive() : Determine whether the thread is still alive.
  • interrupt() : Interrupts the thread, sends an interrupt signal to the thread, but does not necessarily terminate the execution of the thread.
  • isInterrupted() : Determine whether the thread is interrupted.
  • setName(String name) : Set the name of the thread.
  • getName() : Get the name of the thread.
  • suspend() : Deprecated, suspends the execution of the thread.
  • resume() : Deprecated, resumes the execution of the thread.
  • setPriority(int priority) : Set the priority of the thread, the value range is 1-10, and the default is 5.
  • getPriority() : Get the priority of the thread.
  • setDaemon (boolean on) set to daemon thread

Let's introduce several commonly used member methods that are not easy to understand:

1.setPriority(int priority)getPriority()

setPriority(int priority)The method is used to set the priority of the thread, the parameter priorityindicates the priority of the thread, the value range is 1-10, and the priority is 5 by default . Among them, 1 represents the lowest priority and 10 represents the highest priority.

getPriority()The method is used to get the priority of the thread, and the return value is the priority of the thread.

Thread priority is used to specify the priority order of threads when competing for CPU resources. However, priority is not an absolute order of execution, it is only a suggestion to the operating system for thread scheduling.

The emergence of priority is because when the thread in our JAVA is scheduled by the CPU, it adopts preemptive scheduling , that is, the higher the priority, the easier it is to grab the scheduling opportunity. In addition to preemptive scheduling, we also have Non-preemptive scheduling , that is, the CPU schedules threads in turn, and there is no randomness.

Note the following points:

  1. Different operating systems may handle thread priority differently.
  2. The priority of a thread is not guaranteed to execute as expected, because the priority may be affected by the operating system's scheduling algorithm.
  3. You should not rely too much on the priority of threads to implement business logic, because this may lead to poor portability of the code.

Generally speaking, the default priority can be used in the application, unless there are special requirements. At the same time, you should avoid modifying the priority of threads too frequently, so as not to cause problems such as priority skew.

2.setDaemon(boolean on)

setDaemon(boolean on)It is a method provided by the Thread class to set the daemon state of the thread. When a thread is set as a daemon thread, it will become a "waiter" for all non-daemon threads in the JVM. After all non-daemon threads end, the JVM will automatically exit, thereby terminating the execution of the daemon threads.

Specifically, the characteristics of daemon threads are as follows:

  1. Daemon threads are usually used to provide background services or auxiliary functions without affecting the main business logic of the program.
  2. The daemon thread does not affect the normal termination of the JVM. Even if there are still daemon threads executing, the JVM will automatically exit.
  3. When all non-daemon threads are finished, the daemon thread will be automatically terminated without waiting for the task to complete.

Use setDaemon(true)to set the thread as a daemon thread, use setDaemon(false)to set the thread as a user thread (the default).

Note the following points:

  1. setDaemon()The method can only be called before the thread is started, and once the thread is started, the daemon state cannot be modified.
  2. Daemon threads cannot hold any locks that can monopolize resources, because they may be terminated at any time, which may cause problems such as incorrect release of resources or inconsistent state.
  3. Daemon threads are not guaranteed to complete their tasks, so special care must be taken when writing daemon threads to ensure that they do not interfere with the correct execution of the program.

Daemon threads are mainly used to provide services in the background or perform some continuously running tasks, such as garbage collection threads, timing task threads, and so on. Under normal circumstances, the threads we create in the main thread are all user threads, that is, non-daemon threads.

3. join() and yield()

Both join() and yield() are methods for thread control and collaboration.

  1. join()

    • join()Method is used to wait for the calling thread to complete its execution before continuing with the current thread.
    • join()Calling a method in another thread B in one thread A will block the current thread A until the execution of thread B is completed.
    • This is usually used for cooperation between multiple threads to ensure that one thread continues to execute after another thread completes.
    • If join()a timeout is specified in the method, the current thread will wait for the specified time, and continue execution if the timeout has not yet expired.
  2. yield()

    • yield()method is a thread's static method that yields execution to the current thread, suspending it so that other threads of equal or higher priority can execute.
    • yield()The role is to improve the execution efficiency and responsiveness of threads.
    • When a thread calls yield()a method, it changes from the running state to the ready state, yields the CPU execution right, and then competes with other threads with the same or higher priority for CPU resources.
    • Note that yield()the method does not guarantee that the current thread will suspend execution, it just provides a hint to the thread scheduler that thread switching can be performed.

It should be noted that join()methods can be used for thread cooperation, while yield()methods are used for thread scheduling. join()The method will block the thread until the execution of the target thread is completed, and yield()the method will actively give up the CPU execution right, so that other threads have the opportunity to execute.

Summarize:

        In this article, we introduce three methods of using threads and common member methods in thread classes. Multithreading is an important means to deal with high concurrency problems, so we must learn multithreading well.

If my content is helpful to you, please like, comment and bookmark . Creation is not easy, everyone's support is my motivation to persevere!

 

Guess you like

Origin blog.csdn.net/fckbb/article/details/132092021