1, Introduction to implementation method
There are three ways to create threads in java
The second interface implementation is commonly used, because the way to implement the interface is more flexible than the way to inherit classes, and it can also reduce the coupling between programs.
2, Inherit Thread class
Thread class is the parent class of all thread classes, which implements the extraction and encapsulation of threads
Implementation steps:
- Define a class, inherit the Thread class, and override the run method of the class. The run method body is the completed task.
- Create an object of Thread class, that is, create a child Thread
- Start the thread with the start method of the thread object
Create a ticketing system Demo
package com.example.threaddemo; //Define a class that inherits the Thread class public class SellTickets extends Thread{ private int count = 100; //Rewrite the run method of this class. The body of the run method is the completed task. @Override public void run() { while (count > 0){ count--; System.out.println(Thread.currentThread().getName() + "surplus" + count + "Ticket"); } } }
Writing test classes
package com.example.threaddemo; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class ThreadDemoApplicationTests { public static void main(String[] args) { //Create an object of Thread class, that is, create a child Thread SellTickets s1 = new SellTickets(); SellTickets s2 = new SellTickets(); SellTickets s3 = new SellTickets(); //Start the thread with the start method of the thread object s1.start(); s2.start(); s3.start(); } }
result
It indicates that three threads execute separately, with theout sequence
3, Implement Runnable interface
Use the Runnanle interface and start the multithreading step:
- Write an implementation class to implement the Runnable interface, and rewrite the run method of the class. The run method body is the completed task.
- Create an object of a class that implements the Runnable interface
- Use the implementation class object to create a child thread
- Call the start method of the thread object to start the thread
The ticket class implements the Runnable interface
package com.example.threaddemo; //Define a class to implement the Runnable interface public class SellTickets implements Runnable{ private int count = 100; //Rewrite the run method of this class. The body of the run method is the completed task. @Override public void run() { while (count > 0){ count--; System.out.println(Thread.currentThread().getName() + "surplus" + count + "Ticket"); } } }
Writing test classes
package com.example.threaddemo; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class ThreadDemoApplicationTests { public static void main(String[] args) { //Create an object of a class that implements the Runnable interface SellTickets s = new SellTickets(); //Creating child threads using objects Thread t1 = new Thread(s); Thread t2 = new Thread(s); Thread t3 = new Thread(s); //Start the thread with the start method of the thread object t1.start(); t2.start(); t3.start(); } }
result
4, Comparison of two methods
- Inherit Thread:
Advantages: simple coding. To access the current thread, in addition to using Thread.currentThread(), you can also use the super keyword
Disadvantages: because java inherits multiple implementations, it cannot inherit other classes if it inherits Thread
- Implement Runnable
Advantages: multiple implementations, can inherit other classes. Multiple threads can share the same object, which is suitable for processing the same resource.
Disadvantages: it is a little complex. You can only use Thread.currentThread() to access the current thread
5, The difference between the start() and run() methods
- The start() method creates a new thread and lets the thread execute the run() method.
- The call to run() can also be executed normally. However, you can't create a new thread. Instead, you call the run() method in the current thread, just as an ordinary method call.
6, Creating threads through Callable and Future
Java provides a Callable interface, which is an enhanced version of the Runnable interface. The Callable interface provides a call() method, which can be regarded as the execution body of a thread, but the call() method is more powerful than the run() method.
- The call() method can have a return value.
- The call() method can declare that an exception is thrown.
The steps are as follows:
- Create an implementation class of the Callable interface and implement the call() method. The call() method will be used as the execution body of the thread, and the call() method has a return value, and then create an instance of Callable. Starting with Java 8, you can create Callable objects directly using Lamda expressions.
- Use the FutureTask class to wrap the Callable object, which encapsulates the return value of the call() method of the Callable object.
- Create and start a new Thread using the FutureTask object as the target of the Thread object.
- Call the get() method of the FutureTask object to get the return value after the execution of the child thread.
Test class code
package com.example.threaddemo; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; @SpringBootTest class ThirdThread { public static void main(String[] args) { // Create Callable object ThirdThread rt = new ThirdThread(); // First create a callable < integer > object using a Lambda expression // Use FutureTask to wrap Callable objects FutureTask<Integer> task = new FutureTask<Integer>((Callable<Integer>)() -> { int i = 0; for ( ; i < 100 ; i++ ) { System.out.println(Thread.currentThread().getName() + " Cyclic variable of i Value of:" + i); } // The call() method can have a return value return i; }); for (int i = 0 ; i < 100 ; i++) { System.out.println(Thread.currentThread().getName() + " Cyclic variable of i Value of:" + i); if (i == 20) { // The essence is to create and start a thread with a Callable object new Thread(task , "Thread with return value").start(); } } try { // Get thread return value System.out.println("Return value of child thread:" + task.get()); } catch (Exception ex) { ex.printStackTrace(); } } }
result
explain
The program first creates a Callable object using a Lamda expression, and then wraps the instance into a FutureTask object. In the main thread, when the loop variable i is equal to 20, the program starts the thread with the futruetask object as the target. The program finally calls the get() method of the FutrueTask object to return the return value of the call() method. This method will cause the main thread to be blocked until the call() method ends and returns, so the return value of the child thread is always the last output of the call.