(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.