brief introduction
Creating threads is the most basic operation in multithreaded programming
1. Inherit Thread class and override run() method
public class CreatingThread01 extends Thread { @Override public void run() { System.out.println(getName() + " is running"); } public static void main(String[] args) { new CreatingThread01().start(); new CreatingThread01().start(); new CreatingThread01().start(); new CreatingThread01().start(); } }
The disadvantage of inheriting Thread class and overriding run() method is that a class can only inherit one parent class. If this class already inherits other classes, this method cannot be used.
2. Implement the Runnable interface
public class CreatingThread02 implements Runnable { @Override public void run() { System.out.println(Thread.currentThread().getName() + " is running"); } public static void main(String[] args) { new Thread(new CreatingThread02()).start(); new Thread(new CreatingThread02()).start(); new Thread(new CreatingThread02()).start(); new Thread(new CreatingThread02()).start(); } }
The advantage of implementing Runnable interface is that a class can implement multiple interfaces without affecting its inheritance system
3. Implementation of anonymous inner class lambda
public class CreatingThread03 { public static void main(String[] args) { // Thread anonymous class, overriding thread's run() method new Thread() { @Override public void run() { System.out.println(getName() + " is running"); } }.start(); // Runnable anonymous class, implementing its run() method new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + " is running"); } }).start(); // As above, use lambda expression function programming new Thread(()->{ System.out.println(Thread.currentThread().getName() + " is running"); }).start(); } }
The way to use anonymous classes is to rewrite the run() method of Thread, to pass in the anonymous class of Runnable, and to use the lambda method. Now, the third method (java8 +) is generally used, which is simple and fast.
4. Implement Callabe interface
public class CreatingThread04 implements Callable<Long> { @Override public Long call() throws Exception { Thread.sleep(2000); System.out.println(Thread.currentThread().getId() + " is running"); return Thread.currentThread().getId(); } public static void main(String[] args) throws ExecutionException, InterruptedException { FutureTask<Long> task = new FutureTask<>(new CreatingThread04()); new Thread(task).start(); System.out.println("Waiting for the task to be completed"); Long result = task.get(); System.out.println("Task result:" + result); } }
By implementing the Callabe interface, you can get the results of thread execution. FutureTask actually implements the Runnable interface.
5. Timer (java.util.Timer)
public class CreatingThread05 { public static void main(String[] args) { Timer timer = new Timer(); // Every 1 second timer.schedule(new TimerTask() { @Override public void run() { System.out.println(Thread.currentThread().getName() + " is running"); } }, 0 , 1000); } }
Timer java.util.Timer can be used to quickly implement the timer task, which actually implements the Runnable interface.
6. thread pool
public class CreatingThread06 { public static void main(String[] args) { ExecutorService threadPool = Executors.newFixedThreadPool(5); for (int i = 0; i < 100; i++) { threadPool.execute(()-> System.out.println(Thread.currentThread().getName() + " is running")); } } }
Using thread pool can reuse threads and save system resources
7. Parallel computing (Java8 +)
public class CreatingThread07 { public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); // Serial, print 12345 list.stream().forEach(System.out::print); System.out.println(); // Parallel, printing results are random, such as 35214 list.parallelStream().forEach(System.out::print); } }
Using parallel computing can improve the efficiency of program running and multithread parallel execution
8.Spring asynchronous method
First, the springboot boot class is annotated with @ EnableAsync (@ EnableAsync is supported by spring. Here is an example to use springboot).
@SpringBootApplication @EnableAsync public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
Second, the method is annotated with @ Async.
@Service public class CreatingThread08Service { @Async public void call() { System.out.println(Thread.currentThread().getName() + " is running"); } }
Then, test cases as like as two peas are using the general Service method.
@RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) public class CreatingThread08Test { @Autowired private CreatingThread08Service creatingThread08Service; @Test public void test() { creatingThread08Service.call(); creatingThread08Service.call(); creatingThread08Service.call(); creatingThread08Service.call(); } }
The operation results are as follows:
task-3 is running task-2 is running task-1 is running task-4 is running
You can see that each time you execute a method, you use a different thread. The method of using Spring asynchronous method can be said to be quite convenient. It is suitable for some methods that are not logically related and suitable for asynchronous invocation, such as the function of sending short messages.
summary
(1) Inherit the Thread class and override the run() method;
(2) Implement the Runnable interface;
(3) Anonymous inner class;
(4) Implement Callabe interface;
(5) Timer (java.util.Timer);
(6) Thread pool;
(7) Parallel computing (Java8 +);
(8) Spring asynchronous method;