Understanding threads
A process is divided into multiple independent execution streams, called threads
Back to the previous example, a class should not only send and receive homework, but also do blackboard newspapers and clean up. If there is only the monitor, it is not only inefficient but also time-consuming. In order to complete the task as soon as possible, the monitor can distribute the task to other students. Therefore, there are three execution streams to complete the task, but they are essentially serving the class.
At this time, this situation is called multithreading, which decomposes a large task into different small tasks and gives them to different execution streams for execution.
Among them, all students should report to the monitor after completing the task, so the monitor is the main thread.
Each process has at least one thread, the main thread
Difference between process and thread
- Process is the smallest unit of system resource allocation, and thread is the smallest unit of system scheduling
- There is at least one thread in a process
- Resources can be shared between threads in a process
- Processes are independent, and threads interact with each other (if an exception occurs to a thread, the whole process may be terminated, and all threads in the process will also be terminated)
Upper code
import java.util.Random; public class ThreadDemo { private static class MyThread extends Thread { @Override public void run() { Random random = new Random(); while (true) { // Print thread name System.out.println(Thread.currentThread().getName()); try { // Random stop for 0-9 seconds Thread.sleep(random.nextInt(10)); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) { MyThread t1 = new MyThread(); MyThread t2 = new MyThread(); MyThread t3 = new MyThread(); t1.start(); t2.start(); t3.start(); Random random = new Random(); while (true) { // Print thread name System.out.println(Thread.currentThread().getName()); try { Thread.sleep(random.nextInt(10)); } catch (InterruptedException e) { // Random stop for 0-9 seconds e.printStackTrace(); } } } }
Thread-0 Thread-0 Thread-2 Thread-1 Thread-2 Thread-1 Thread-0 Thread-2 main main Thread-2 Thread-1 Thread-0 Thread-1 main Thread-2 Thread-2 wait
Use the jconsole command to observe threads
Advantages of multithreading
public class ThreadAdvantage { // Multithreading does not necessarily improve the speed. It can be observed that the actual running effect is different with different count s private static final long count = 10_0000_0000; public static void main(String[] args) throws InterruptedException { // Use concurrency concurrency(); // Use serial mode serial(); } private static void concurrency() throws InterruptedException { long begin = System.nanoTime(); // Use a thread to calculate the value of A Thread thread = new Thread(new Runnable() { @Override public void run() { int a = 0; for (long i = 0; i < count; i++) { a--; } } }); thread.start(); // The value of b calculated in the main thread int b = 0; for (long i = 0; i < count; i++) { b--; } // Wait for the thread thread to finish running thread.join(); // Statistical time long end = System.nanoTime(); double ms = (end - begin) * 1.0 / 1000 / 1000; System.out.printf("Concurrent: %f millisecond%n", ms); } private static void serial() { // All the values of a and b are calculated in the main thread long begin = System.nanoTime(); int a = 0; for (long i = 0; i < count; i++) { a--; } int b = 0; for (long i = 0; i < count; i++) { b--; } long end = System.nanoTime(); double ms = (end - begin) * 1.0 / 1000 / 1000; System.out.printf("serial : %f millisecond%n", ms); } }
//Operation results Concurrent: 399.651856 millisecond serial : 720.616911 millisecond
It can be seen that multithreading can improve the overall running efficiency of the program on some occasions
Method of creating thread
Method 1: inherit Thread class
class MyThread extends Thread { @Override public void run() { System.out.println("Here is the code that the thread runs"); } }
MyThread t = new MyThread(); t.start(); // The thread starts running
Advantage: this represents the current thread and does not need to pass thread Currentthread() to get the reference of the current thread
Method 2: implement Runnable interface
The Thread object is created by implementing the Runnable interface and passing the Runnable object as the target parameter when calling the Thread construction method
class MyRunnable implements Runnable { @Override public void run() { System.out.println(Thread.currentThread().getName() + "Here is the generation of thread running code"); } }
Thread t = new Thread(new MyRunnable()); t.start(); // The thread starts running
Advantage: it can avoid the limitation of class inheritance
But you need to pass thread Currentthread() to get the reference of the current thread
Method 3: use anonymous inner class
// Create Thread subclass objects using anonymous classes Thread t1 = new Thread() { @Override public void run() { System.out.println("Create using anonymous classes Thread Subclass object"); } }; // Creating Runnable subclass objects using anonymous classes Thread t2 = new Thread(new Runnable() { @Override public void run() { System.out.println("Create using anonymous classes Runnable Subclass object"); } });
Method 4: use lambda expression
Thread t3 = new Thread(() -> System.out.println("Create using anonymous classes Thread Subclass object")); Thread t4 = new Thread(() -> { System.out.println("Create using anonymous classes Thread Subclass object"); });
Fan Wai: how to use jconsole command
- Find the jdk of the current host
- Select jconsole exe
- Select the program you are running in the local process and click Connect