What is multithreading
Multithreading is the smallest unit that the operating system can schedule. It is included in the process and is the actual operation unit of the process. The number of hardware CPU cores corresponds to the number of threads that can be executed at the same time.
Specific evolution path
IO database interaction, disk brushing, caching, distributed, middleware and threads are everywhere from single node to distributed computer.
Why use threads
From the start of a program to the running of a process, the CPU is required to schedule execution, but the CPU computing speed is much faster than the disk IO computing storage, then the difference CPU in the middle will be in a waiting state, that is, blocking, resulting in a waste of CPU resources.
All leads to multiple processes and then to multiple threads. A process can have N threads
Multithreading in Java
1. Multithreading features
- asynchronous
I don't have to wait for the result to come back. After I send the request, I don't have to wait for the result, and then I can do other things
Specific embodiment: after the user registers, then asynchronously draw and send e-mail, etc
- parallel
I can draw a lottery and send a welcome email at the same time. It is used when there is no association between the two threads
2. Use in Java
- There are three ways to use them. See the following code respectively
class Test0 extends Thread{ @Override public void run() { System.out.println("inherit Thread"); } } class Test1 implements Runnable{ @Override public void run() { System.out.println("realization Runnable Interface"); } } class Test2 implements Callable { @Override public Object call() throws Exception { System.out.println("realization Callable Interface,And get the return value"); Thread.sleep(10000); return "call Thread return value"; } } //main method call public static void main(String[] args) throws Exception { //Inherit Thread new Test0().start(); //Implement Runnable interface new Thread(new Test1()).start(); //Implement the callable interface to obtain the return value Test2 test2 = new Test2(); FutureTask<Object> task = new FutureTask<Object>(test2); //Here, the jvm first calls the run method in FutureTask, and then calls result = c.call(); To our implementation method //And save the result to the variable outcome new Thread(task).start(); //Get the results through report and wait before the execution is finished System.out.println(task.get()); }
Principle of multithreading
1. Source code analysis, start here
class Test0 extends Thread{ @Override public void run() { System.out.println("inherit Thread"); } }
2. Start thread
//The start method starts a thread, and run() executes synchronously once new Test0().start(); //Come to the Thread class public synchronized void start() { if (threadStatus != 0) throw new IllegalThreadStateException(); //Join to thread group group.add(this); boolean started = false; try { //Mainly look at this### start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ } } } //The next discovery is the native method private native void start0();
The above native method is finally called into the JVM thread.cpp, and then the JVM creates a thread according to the corresponding OS that will be called by different operating systems, and this method will tell the cpu to start a thread. Then, when executing this thread in the cpu scheduling algorithm, it will call back to the JVM, and finally call the run method in the thread, that is, our handwritten code, and the thread starts to execute
3. Thread diagram
Thread life cycle
Enable - > sleep wait - > lock synchronized lock - > execution completion / abnormal end
When the thread is running, you can view the stack log through [jstack process number]
Thread stop
1. First look at the friendly end and stop through the interrupted interrupt instruction
Thread thread = new Thread(() -> { while (!Thread.currentThread().isInterrupted()) { System.out.println(11111); } }, "N1"); thread.start(); Thread.sleep(1000); //Stop through the interrupt ID of the current thread thread.interrupt(); System.out.println(22222);
2. Violent end must be used when the block executed in the thread cannot end normally, such as dead loop, blocking and waiting
public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(() -> { while (!Thread.currentThread().isInterrupted()) { try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println(3333); } System.out.println(11111); } }, "N1"); thread.start(); Thread.sleep(3000); //Sending an interrupt instruction will throw InterruptedException up thread.interrupted(); System.out.println(22222); }
- results of enforcement
11111 11111 22222 3333 11111 11111
- From the above results, we can see that the code will not stop at all, but will run all the time. When the interrupt instruction is sent, why not stop? Look at these two pieces of code first
try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println(3333); } try { Thread.currentThread().wait(); } catch (InterruptedException e) { e.printStackTrace(); }
- All waiting or blocking operations of the thread will throw this exception, because it may be waiting or blocking all the time, so the thread interrupt is required. However, the thread is clearly interrupted but does not stop. This process is called thread interrupt reset
try { Thread.sleep(1000); } catch (InterruptedException e) { //The choice here lies with the developer himself //After the InterruptedException exception is thrown, the interrupt state will be restored, which is called reset //Then, if you want to interrupt, use this Thread.currentThread().interrupt() //Then do something after the exception interrupt System.out.println(3333); }
3. Thread reset
When the thread interrupted ID is given, the current thread will not end immediately, but will throw an InterruptedException, which needs to be determined by the developer, because some other records may need to be made after the exception interrupt.
Let's look at code analysis
public static boolean interrupted() { //Identify the current thread as true return currentThread().isInterrupted(true); } //Next, go to the native method, which is the operation done in the JVM //This thread is given an identity. When the thread reads the identity, it will throw an exception and reset the interrupted state private native boolean isInterrupted(boolean ClearInterrupted);
The above is the whole content of multithreading and threading into source code analysis.
Next: Troubleshooting of deadlock, livelock and sudden surge of CPU in Java Server
I have no intention of going or staying. I watch the flowers bloom and fall in front of the court; Not surprised by flattery or disgrace, it spreads with the clouds outside the sky