From the operating system, can be civilian system is the first DOS, but the traditional DOS system has a feature: the computer virus after the system will crash, because the traditional DOS system is a single process processing method. Then came the Windows era, then the use of multi-process processing, in the same time period there will be more than one program concurrent execution, take the CPU resources in turn.
However, the start-up and destruction of the process is still very slow. So later people began to try to do further optimizations on the process, then the concept of threading was created, namely, that threads are augmented on a process basis. Thread startup and destruction will be faster than the process, one process can be divided into multiple threads, and the process disappears, the thread must also disappear, Java is one of the few languages that support multithreaded programming.
If you want to implement multi-threaded development, it must be like the main class exists, but also need a thread of the principal class, but this class can not be defined separately, it must inherit the thread class or implement the Runnable interface (if the actual development of the Runnable interface must be).
4.1. Inherit the Thread class
The thread's principal class only needs to inherit the thread class through the extends keyword, so this class can be used for threading control, and when inheriting the thread class, the user also needs to overwrite the run () method "Publicvoid Run ()" in the Thread class.
Example: defining a thread's principal class
class MyThread extends Thread { Private String name; Understand the name of the object Public MyThread (String name) { this. Name = name; } @Override Public void Run () {//thread's Main method for (int x = 0; x < x + +) { System. out. println (this. Name + ", x =" + x); } } } |
At this point, every object in the Mythread class is a thread, so multiple threads can be produced.
However, when the thread principal class definition is complete, it must be accessed through an object, but not the run () method in the class, but the start () method of the Thread class: "Publicvoid Start ()". Calling this method is equivalent to calling the run () method.
Example: starting multithreading
public class testdemo { public static void main (string[] args) { mythread MtA = new mythread ("Thread A"); mythread MtB = New MyThread ("thread B"); mythread MtC = New MyThread ("Thread C"); mta.start (); mtb.start (); mtc.start (); &NBSP;&NBSP;&NBSP;&NBSP;} } |
If you are using the run () method, which is actually just a normal invocation of a method, it will be executed sequentially, and if the start () method is called, multiple threads will be started and multiple threads run concurrently with each other.
question: with a short analysis, you should already know the basics of multithreaded operation, but why not call run () with start ()?
To facilitate understanding, open the definition of the start () method in the thread class:
Public synchronized void Start () { if (Threadstatus! = 0) Throw New Illegalthreadstateexception (); Group.add (this); Boolean started = false; Try { start0 (); started = true; } finally { Try { if (!started) { Group.threadstartfailed (this); } } Catch (Throwable ignore) { } } } Private native void start0 (); |
This method throws an "Illegalthreadstateexception" exception, but if you throw an exception manually using throw, you should use Try...catch processing. However, there is no mandatory requirement at this time, because by observing the "illegalthreadstateexception" Inheritance structure:
Java.lang.Object Java.lang.Throwable Java.lang.Exception java.lang.RuntimeException Java.lang.IllegalArgumentException Java.lang.IllegalThreadStateException |
Because of the RuntimeException subclass, this exception is typically thrown when a thread is repeatedly started. So a thread can only be started once.
It can be found that the Start0 () method is called automatically when the start () method is called, and a native keyword is found at the declaration of the Start0 () method, which means that the code will be implemented through the native function locally.
The operation of the thread must be CPU resource scheduling, each operating system resource scheduling is not the same, so this method is actually implemented by the JVM, then write only a name of an abstract method, and the specific implementation will be based on different operating systems to overwrite, so that portability is achieved.
Therefore, it can be concluded that when the user executes the start () method, it means that the operating system is provisioned, and the run () method is then executed. That is, you must use the start () method in the thread class whenever you start multiple threads .
4.2. Implement Runnable interface
Inheritance between classes and classes is not recommended to use, but the class implementation interface is a recommended feature, in Java in order to solve the problem of single inheritance constraints, so also provide a runnable interface, the user only need to let the thread of the Principal class implementation runnable interface.
Example: observing the definition structure of the Runnable interface
Public Interface Runnable { Public void run (); } |
Example: defining a thread principal class using runnable
class MyThread implements Runnable { Private String name; Public MyThread (String name) { this. Name = name; } @Override Public void Run () {//thread's Main method for (int x = 0; x < x + +) { System. out. println (this. Name + ", x =" + x); } } } |
The previous analysis can conclude that, as long as the thread start must rely on the thread class's start () method, if now a class directly inherits the thread class, you can inherit the next start () method, but at this time the implementation is the Runnable interface, Then there will be no start () that can be inherited. So here's a look at the definition of the constructor method in the Thread class: "PublicThread (Runnable target)". Discovery can receive a runnable interface subclass object.
Example: starting multithreading
Public class Testdemo { Public Static void Main (string[] args) { MyThread MtA = new MyThread ("Thread A"); MyThread MtB = new MyThread ("thread B"); MyThread MtC = new MyThread ("Thread C"); New Thread (MtA). Start (); New Thread (MtB). Start (); New Thread (MtC). Start (); } } |
At this point the functions are exactly the same, but it is clear that using runnable is more reasonable than using thread.
4.3. Difference between two ways of realization (interview question)
After a series of analysis has been clear the two ways to implement multithreading, but these two methods from the structure of the use of runnable, but in addition to this point, there are other differences?
So first look at the definition of the thread class:
public class Thread extends Object implements Runnable |
found that the original thread class also implements the Runnable interface, so a very interesting thing happened.
The structure of thread is the structure design of a proxy class, but it is not so complete. If it is a purely proxy design pattern, then the user should call the thread class's run () method, but now the call is the start () method (not the method provided by the Runnable interface), so throughout the operation although the form is the agent structure, but eventually there is a difference, And this difference is due to historical reasons.
In addition to this basic connection, there is little difference: Multithreading using the Runnable interface is more likely to represent the concept of data sharing than multithreading implemented using the thread class.
Example: writing a simple ticket-selling procedure, using the thread class implementation (generating three thread objects to sell together)
Package Cn.mldn.demo; class MyThread extends Thread { Private int ticket = 5; Let's say 5 tickets. @Override Public void Run () {//thread's Main method for (int x = 0; x < x + +) { if (this. Ticket > 0) { System. out. println ("sell ticket: Ticket =" + this. Ticket-); } } } } Public class Testdemo { Public Static void Main (string[] args) { New MyThread (). Start ();//A thread New MyThread (). Start ();//Two threads New MyThread (). Start ();//Three threads } } |
This time found that each thread object has its own five tickets for sale, does not meet the requirements.
Example: using the Runnable interface to implement
Package Cn.mldn.demo; class MyThread implements Runnable { Private int ticket = 5; Let's say 5 tickets. @Override Public void Run () {//thread's Main method for (int x = 0; x < x + +) { if (this. Ticket > 0) { System. out. println ("sell ticket: Ticket =" + this. Ticket-); } } } } Public class Testdemo { Public Static void Main (string[] args) { MyThread MT = new MyThread (); New Thread (MT). Start ();//A thread New Thread (MT). Start ();//Two threads New Thread (MT). Start ();//Three threads } } |
Interview Question: Please explain the difference between the two ways of implementing multi-Threading. Write the program separately to explain?
· Two ways of implementing Multithreading: inheriting the Thread class and implementing the Runnable interface;
· If the thread class is inherited, it is limited by the single inheritance, and it is inconvenient to represent the concept of data sharing, the thread class is a subclass of the runnable interface;
· If the Runnable interface is implemented, it will not be affected by single inheritance, and it can easily represent the operation of data sharing.
· However, no matter how you use it, you will eventually have to start multithreading by using the Start () method of the thread class.
Java Learning-Processes and threads