Process is the basic unit of system resource allocation and scheduling. Thread is the smallest unit of program running.
Multiple threads in a process will share process resources, which will lead to a series of data security and consistency problems. We need to seriously learn the relevant knowledge of concurrent system to ensure the security of critical zone resources.
So how does java implement multithreading?
java implements such a class called Thread, which is the Thread object of java
Entering the Thread source code, you can see that the source code provides two ways to create multithreading
Method 1: inherit Thread class
class PrimeThread extends Thread { long minPrime; PrimeThread(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . } } PrimeThread p = new PrimeThread(143); p.start();
Method 2: inherit Runnable interface
class PrimeRun implements Runnable { long minPrime; PrimeRun(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . } }
Write the code we want to run to the run() method, so that the new thread will execute the code in the run() function body
If we use the inheritance Thread class, the defect lies in the single inheritance limit of java. After implementing the Runnable interface, we can inherit other classes to achieve more functions and better scalability.
As you can see from the Thread source code, there are many construction methods
among
public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0); }
We can see that we only need to pass an instance that implements the Runnable interface to implement multithreading. Therefore, I randomly found a class that implements the Runnable interface to experiment. Yes.
TimerTask timerTask = new TimerTask() { @Override public void run() { for(int i=1;i<=20;i++){ System.out.printf("I am TimerTask-1:%d\n",i); } } }; Thread threadThree = new Thread(timerTask); threadThree.start();
In the Thread source code, there are such fields
/* What will be run. */ private Runnable target;
The init() method will be called in the constructor, and the init() method will have the following code
this.target = target
The Thread class overrides the run() function
@Override public void run() { if (target != null) { target.run(); } }
Therefore, the Thread.run() method actually uses the run() method that we passed in to implement the instance of the Runnable interface
Full code:
import java.util.TimerTask; public class ThreadTest { public static class MyThread extends Thread{ @Override public void run(){ for(int i=1;i<=20;i++){ System.out.printf("I am MyThread:%d\n",i); } } } public static class RunnableTest implements Runnable{ @Override public void run() { for(int i=1;i<=20;i++){ System.out.printf("I am RunnableTest:%d\n",i); } } } public static void main(String[] args){ MyThread thread = new MyThread(); thread.start(); RunnableTest runnableTest = new RunnableTest(); Thread threadTwo = new Thread(runnableTest); threadTwo.start(); TimerTask timerTask = new TimerTask() { @Override public void run() { for(int i=1;i<=20;i++){ System.out.printf("I am TimerTask-1:%d\n",i); } } }; TimerTask timerTaskCopy = new TimerTask() { @Override public void run() { for(int i=1;i<=20;i++){ System.out.printf("I am TimerTask-2:%d\n",i); } } }; Thread threadThree = new Thread(timerTask); threadThree.start(); Thread threadFour = new Thread(timerTaskCopy); threadFour.start(); } }
The experimental results are as follows. If the feeling is not obvious, the range of i traversal can be increased
In the beauty of concurrent programming, the author also recommends FutureTask, which can return a result after the task is executed.
The content of the article comes from the induction and sorting of network materials and books and your own practice. If you have any mistakes or deficiencies, please don't hesitate to give advice.