Author: Tang Tong

preface

Thread creation is the most basic operation in multithreaded programming. There are about 8 ways to create threads. Do you know?

1. Inherit Thread and override the 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(); }}Copy the code
The downside of inheriting Thread and overwriting the run() method is that a class can only inherit from one parent class, not if that class already inherits from another.

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(); }}Copy the code
Implement the Runnable interface. The advantage of this approach is that a class can implement multiple interfaces without affecting its inheritance system.

Anonymous inner classes

Public class CreatingThread03 {public static void main(String[] args) {public static void main(String[] args)Thread() {
 @Override
 public void run() {
 System.out.println(getName() + " is running"); } }.start(); // Runnable anonymous class that implements its run() method new Thread(new)Runnable() {
 @Override
 public void run() {
 System.out.println(Thread.currentThread().getName() + " is running"); } }).start(); New Thread(()->{system.out.println (thread.currentThread ().getName() +)" is running"); }).start(); }}Copy the code
We can override Thread’s run() method, pass in Runnable’s anonymous class, or use lambda. The third option (Java8 +) is now simple and fast.

4. Implement the 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 complete");
 Long result = task.get();
 System.out.println("Mission Results:"+ result); }}Copy the code
Implementing the Callabe interface to 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(); // Run timer.schedule(new) every 1 secondTimerTask() {
 @Override
 public void run() {
 System.out.println(Thread.currentThread().getName() + " is running"); }, 0, 1000); }}Copy the code
Timer java.util.Timer is a quick way to implement timed tasks, and TimerTask actually implements the Runnable interface.

6. The 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")); }}}Copy the code
Using a 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(); ParallelStream ().foreach (system.out ::print); }}Copy the code
The use of parallel computing, can improve the efficiency of the program running, multithreading parallel execution.

8.Spring async methods

First, the SpringBoot boot class is annotated with @enableAsync (@enableAsync is supported by Spring, so springBoot is a handy example).

@SpringBootApplication @EnableAsync public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }}Copy the code
Second, the method is annotated with @async.

@Service
public class CreatingThread08Service {
 @Async
 public void call() {
 System.out.println(Thread.currentThread().getName() + " is running"); }}Copy the code
Then, the test case is exactly the same as using the normal Service method.

@RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) public class CreatingThread08Test { @Autowired  private CreatingThread08Service creatingThread08Service; @Test public voidtest() { creatingThread08Service.call(); creatingThread08Service.call(); creatingThread08Service.call(); creatingThread08Service.call(); }}Copy the code
The running results are as follows:

task-3 is running
task-2 is running
task-1 is running
task-4 is running

Copy the code
You can see that the thread is different each time the method is executed.

The use of Spring’s asynchronous methods is quite convenient, and can be applied to some methods suitable for asynchronous invocation where the logic is not related, such as sending SMS functions.

conclusion

(1) Inherit Thread class and rewrite run() method;

(2) Implement 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;

welfare

There are essentially two ways to create a Thread. One is to inherit the Thread class and override its run() method, and the other is to implement the Run () method of the Runnable interface. What is the connection between them?

Look at the following example. What should be output when Thread is inherited and the Runnable interface is implemented?

public class CreatingThread09 {
 public static void main(String[] args) {
 new Thread(()-> {
 System.out.println("Runnable: " + Thread.currentThread().getName());
 }) {
 @Override
 public void run() {
 System.out.println("Thread: "+ getName()); } }.start(); }}Copy the code
At this point, it’s worth taking a look at the source code for the Thread class:

Public class Thread implements Runnable {// Thread implements Runnable instance private Runnable target; publicThread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
 }
 public Thread(Runnable target) {
        init(null, target, "Thread-"+ nextThreadNum(), 0); } private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc, boolean inheritThreadLocals) { // ... // The constructor passes Runnable to target this.target = target; / /... } @Override public voidrun() {// Thread's default run() method. If target is not null, target's run() method is executedif(target ! = null) { target.run(); }}}Copy the code
Does it suddenly open up when you see here? Since the above example inherits Thread and implements the Runnable interface, it essentially overwrites the Thread’s run() method and has no relation to target at all.

So, the above example outputs Thread: thread-0 and only outputs the contents of the run() method that overrides Thread.

The last

Welcome to pay attention to my public number [programmer chasing wind], the article will be updated in it, sorting out the data will be placed in it.