Hello, today for everyone to share the Java thread, quickly take out a small notebook to write it down

Brief introduction:

Thread is the smallest unit of operating system scheduling. In multi-core environment, multiple threads can be executed at the same time. If properly used, it can significantly improve program performance.

A preliminary understanding of threads

1. What is a thread

When the operating system runs a program, it starts a process for it. For example, starting a Java program creates a Java process. The smallest unit of modern operating system scheduling is thread, also known as Light Weight Process (Light Weight Process), a Process can create one to multiple threads, threads have their own counters, stacks and local variables and other attributes, and access to shared memory variables. The processor executes the program by quickly switching these threads.

Java itself is multithreaded

Sample code:

Output results (not necessarily consistent) :

[6]Monitor ctrl-break

[5]Attach a Listener // Attach a thread of communication between JVM processes

[4]Signal Dispatcher // The thread that processes signals sent to the JVM

[3]Finalizer // Finalizer thread for calling the object

[2]Reference Handler // Clear the thread of Reference

[1] Main // Main thread, user program entry

Conclusion:

As you can see from the output, Java programs themselves are multithreaded. Instead of just one main thread running, the main thread is running at the same time as multiple other threads.

3. Why multithreading

The benefits of using multiple threads are as follows:

More processor cores

As the number of computer processor cores increases, it develops from high frequency to multi-core technology. Now computers are better at parallel computing, so how to make full use of multi-core processor is now the main problem. Threads are the smallest unit of operating system scheduling. When a program is run as a process, it creates multiple threads, and a thread can only run on one processor at a time. Therefore, a process that can use multithreaded computation and divide its computation logic across multiple processor cores will have a significant performance improvement over a single thread.

Faster response time

In complex business scenarios, we can dispatch non-consistently correlated business to other threads (or use message queues). This reduces the application response time to user requests

A better programming model

Using the multithreaded programming model provided by Java allows programmers to better solve problems without having to think too hard about how to multithread them.

4. Thread priority

Modern operating system basically adopts the way of time slice allocation to schedule threads, that is, the operating system divides CPU operation into time slices, threads will allocate a number of time slices, when the thread time slice is used up, thread scheduling will wait for the next time slice allocation. How long a thread can execute in a CPU schedule depends on how many time slices are divided, and thread priority is a thread attribute that determines whether a thread needs to allocate more or less processor resources.

In Java threads, the priority of a thread can be set from 1 to 10, and the default priority is 5. In theory, threads with a higher priority should allocate more time slices than threads with a lower priority.

Sample code:

Execution Result:

The output shows that the number of times a priority 1 thread executes is very similar to the number of times a priority 10 thread executes, indicating that program correctness is not dependent on the priority of the thread.

5. Thread state

The lifecycle of a thread is as follows:

Example code for viewing the status of a Java thread:

View Java processes using JPS:

ThreadStateDemo process ID is 2576. Type jStack 2576 to see the output:

Summary: Threads are not mandated to be in one state during their life cycle, but rather to switch between states as the code executes.

The Java thread state change diagram looks like this:

Conclusion:

After the thread is created, the start() method is called to start running

After executing wait(), a thread enters the wait state, which depends on other threads to return to the running state

The timeout wait is equivalent to adding the timeout limit on the basis of the waiting state. After reaching the preset timeout period, the system returns to the running state

When a thread executes a synchronized method or code block, the thread that does not acquire the lock will enter the blocking state.

The thread enters the terminating state after executing Runnable’s run() method

Threads blocking the Lock interface in Java’s Concurrent package are in a wait state because the implementation of the Lock interface blocking uses Daemon threads

Daemon threads

Description: Daemon threads are support threads that perform background scheduling and support work in applications. If no non-daemon threads exist in a Java VIRTUAL machine, the Java virtual machine will exit. Daemon threads need to be set before startup, not after. Setting Mode:

Thread.setDaemon(true)

Special note: Daemon threads are used to complete support work, but the Finally block of Daemon threads does not necessarily execute when the Java VIRTUAL machine exits.

Sample code:

Testing:

Output result:

Conclusion: It is not hard to see that the finally block of DaemonRunner’s run method is not executed. This is because when there are no non-Daemon threads in the Java VIRTUAL machine, the virtual machine will exit immediately and all Daemon threads in the virtual machine will terminate immediately. So the DaemonRunner thread is terminated immediately, and finally is not executed.

The thread starts and terminates

1. Construct threads

Before running a thread, you need to construct a thread object. When you construct a thread object, you need to set some thread properties, such as thread group, thread priority, whether it is a daemon thread, thread name, etc.

Code example: from java.lang.thread

Conclusion:

In the above code, a newly built thread object is allocated space by its parent thread, and the child inherits the parent Daemon, priority, contextClassLoader, and inheritable ThreadLocal. A unique ID is also assigned to identify the thread. At this point, a complete runnable thread object is initialized and waiting to run in heap memory.

2. What is a thread interrupt

Interrupts can be understood as an identifying bit property of a thread that indicates whether a running thread has been interrupted by another thread. A Thread responds by checking whether it has been interrupted, using isInterrupted(), or by calling the static thread.interrupted () method to restore the interrupt flag of the current Thread.

It is impossible to determine whether a thread has been interrupted in the following cases:

  1. The thread has been interrupted and isInterrupted() returns false even if it has been interrupted
  2. The InterruptedException method throws an exception. Calling isInterrupted() returns false even if interrupted because the interrupt flag is cleared before throwing InterruptedException.

Sample code:

View the run result:

Conclusion:

The sleepThread throws InterruptedException. The sleepThread’s interrupt flag returns false, even though both threads were interrupted. This is because timeunit.seconds.sleep (SECONDS) throws InterruptedException after the sleepThread’s interrupt flag is cleared. However, busyThread keeps running without throwing an exception, and the interrupt bit is not cleared.

Suspend (), resume(), and stop()

For example:

Thread these three methods, equivalent to QQ music play music when the suspension, recovery and stop operation. (Note that these methods are out of date and not recommended.)

Sample code:

Output result:

Conclusion:

The output of the above code execution is consistent with the API instructions and our expectations, but the seemingly correct code hides many of these problems.

Existing problems:

  • The suspend() method is called without releasing occupied resources (such as locks), which can result in deadlocks
  • The stop() method does not guarantee the normal release of resources when terminating a thread, and may cause the program to be in an indeterminate working state

4. Terminate the thread correctly

Call the interrupt() method of the thread

Use a Boolean variable to control whether to stop the task and terminate the thread

Sample code:

Output result:

Summary: The main thread can terminate CountThread by either interrupting or canceling (). The advantage of both methods is that they give the thread a chance to clean up resources when it terminates. It’s safer and more elegant.

Well, this is the end of today’s article, I hope to help you confused in front of the screen