For example, when you turn on the computer and listen to music, and you are still chatting with your girlfriend QQ (oh! You don't have a girlfriend), you can think that there are two processes. For single core CPU, concurrent operation is the illusion given to us by the rapid polling and scheduling of CPU time clock, and for multi-core CPU, it is the real concurrent operation.
1.1 threads
There is at least one thread in a process (also known as lightweight process). Thread is the path of program execution. Each thread has its own local variable table and program counter (pointer to the instruction being executed), And their respective life cycles (it doesn't matter if you don't understand it here. Just look back. For example, you open the chat interface with someone in QQ. At this time, the program should load both chat records and chat interface. If you use single thread (the interface comes out and the chat records haven't been found yet), you will have a bad experience. In this way, you can understand multithreading)
1.2 quickly create and start a thread
For the sake of clarity, I'll briefly talk about the Thread class. Most tutorials may describe that there are two ways to create a Thread (1. Inherit the Thread and rewrite the run method; 2. Inherit the Runnable interface and rewrite the run method). This is not rigorous. why? Let's look at the picture below
Please see that the Runnable interface only defines the run () method, not the start method. Let's take another look at the Thread class source code
Thread implements the Runnable interface and defines the start method
It will be clearer when we use Runnable to create threads later
Get to the point
Inherit the Thread class (the default non guided package under the java.lang package)
Step: 1 Create a class that inherits the Thread class
Step: 2 Override the run () method
Step: 3 Instantiate the object that created the class
Step: 4 Call the start method () to start the thread
public class test { public static void main(String[] args) { //Step 3 Thread thread = new DemoThread(); //Step 4 thread.start(); System.out.println("main method"); } } //First step class DemoThread extends Thread{ //Step two @Override public void run() { System.out.println("run method"); } }
If we run it for many times, we will find that the order of two printing is not certain, which indicates that multiple threads are running. In order to be more obvious, let's try the following code
public class test { public static void main(String[] args) throws InterruptedException { Thread thread = new DemoThread(); thread.start(); for (int i = 0;i<=4;i++){ System.out.println("function main method"); Thread.sleep(100); } } } class DemoThread extends Thread{ @Override public void run() { for (int i = 0;i<=4;i++){ System.out.println("function run method"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }
Operation results
The detailed explanation of the start and sleep methods will be mentioned later. Here we just see the effect of concurrent programming
Implement Runnable interface
Step: 1 Create a class to implement the Runnable interface
Step: 2 Override run method
Step: 3 Create an instance object that implements the class
Step: 4 Because the Runnable interface does not define the start method, and the Thread class has the following constructor, you can use the instance object as a parameter to create a Thread
public class test { public static void main(String[] args) throws InterruptedException { DemoThread demoThread = new DemoThread(); Thread thread = new Thread(demoThread); thread.start(); for (int i = 0;i<=4;i++){ System.out.println("function main method"); Thread.sleep(100); } } } class DemoThread implements Runnable{ @Override public void run() { for (int i = 0;i<=4;i++){ System.out.println("function run method"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }
Is there only a billion changes!
Thread life cycle
Thread class common API
currentThread() | public static native Thread currentThread(); | Returns the current thread |
getName() | public final String getName() { return name; } | Returns the name of the current process (in conjunction with the currentThread method) |
isAlive() | public final native boolean isAlive(); | Judge whether the current thread is active |
Member variables and thread safety
Share data # do not share data
//shared data public class test { public static void main(String[] args) throws InterruptedException { DemoThread demoThread = new DemoThread(); Thread thread1 = new Thread(demoThread); Thread thread2 = new Thread(demoThread); Thread thread3 = new Thread(demoThread); Thread thread4 = new Thread(demoThread); Thread thread5 = new Thread(demoThread); thread1.start(); thread2.start(); thread3.start(); thread4.start(); thread5.start(); } } class DemoThread implements Runnable{ private int num = 5; @Override public void run() { while (num>0){ num--; System.out.println(num); } } }
//Do not share data public class test { public static void main(String[] args) throws InterruptedException { Thread thread1 = new DemoThread(); Thread thread2 = new DemoThread(); Thread thread3 = new DemoThread(); Thread thread4 = new DemoThread(); Thread thread5 = new DemoThread(); thread1.start(); thread2.start(); thread3.start(); thread4.start(); thread5.start(); } } class DemoThread extends Thread{ private int num = 5; @Override public void run() { while (num>0){ num--; System.out.println(num); } } }