(Mobile phone landscape view source more convenient)

The problem

(1) What are the ways to create a thread?

(2) What are their application scenarios?

Introduction to the

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

Inherit the Thread class 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.

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 class

Public class CreatingThread03 {public static void main(String[] args) { New Thread() {@override public void run() {system.out.println (getName() + "running"); } }.start(); // Runnable anonymous class, @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.

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(" wait to finish task "); Long result = task.get(); System.out.println(" result: "+ result); }}Copy the code

Implementing the Callabe interface to get the results of thread execution, FutureTask actually implements the Runnable interface.

Timer (java.util.timer)

public class CreatingThread05 { public static void main(String[] args) { Timer timer = new Timer(); // Execute timer.schedule(new TimerTask() {@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.

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.

Parallel computing (Java8+)

public class CreatingThread07 { public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); 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.

Spring asynchronous 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 void test() {
        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 runningCopy 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;

eggs

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; public Thread() { 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 void run() {// Thread runs () if (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.

Welcome to pay attention to my public number “Tong Elder brother read source code”, view more source code series articles, with Tong elder brother tour the ocean of source code.