Objective
There are three ways to use Java Multithreading: Inheriting the Thread class, implementing the Runnable interface, and creating threads with callable and future, this article describes each of these three methods.
1. Inherit the thread class
The implementation is very simple, just to create a class to inherit the thread class and then rewrite the Run method, in the main method call the class instance object's Start method to achieve multi-threaded concurrency. Code:
Public class MyThread extends Thread {
@Override
Public void run(){
Super.run();
System.out.println("execute child thread...");
}
}
Test Case:
Public class Test {
Public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
System.out.println("main thread...");
}
}
Operation Result:
Of course, the results here do not represent the order in which the threads are executed, the threads are executed concurrently, and the print order may be different if you run them several times. During multi-threaded operation, the CPU executes the thread in an indeterminate way, so the running result is independent of the order of execution or order of the Code, and the result may be different. About the randomness of thread execution There is also a code example later in this article.
Another point to note here is that the Mythread start method should be called in the Main method, not the run () method. The start () method is called to tell the CPU that the thread is ready to execute and that the system has time to execute its run () method. The direct call to the run () method, instead of executing asynchronously, is equivalent to calling the function to execute synchronously sequentially, which loses the meaning of multithreading.
2. Implement Runnable interface
The implementation of this approach is also very simple, that is, the inheritance of the thread class to implement the Runnable interface. The code is as follows:
Public class MyRunnable implements Runnable {
@Override
Public void run() {
System.out.println("execute child thread...");
}
}
Test Case:
Public class Test {
Public static void main(String[] args) {
Runnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
Thread.start();
System.out.println("Main thread running end!");
}
}
Operation Result:
There's nothing to say about running the results, and here in main you can see whether a new thread is actually created or created by thread:
Thread thread = new Thread(runnable);
The function of the thread class is to wrap the run () method into the thread execution body, and then continue to tell the system through start that the thread is ready to be scheduled for execution.
3. Create threads using callable and future
Both of these issues are in the above two ways:
- Unable to get the return value of the child thread
- The Run method can not throw an exception
In order to solve these two problems, we need to use the callable interface. When it comes to interfaces, the Runnable interface implementation class instance is passed in as a parameter to the constructor of the thread class and then executes the contents of the Run method through the start of thread. But callable is not a runnable sub-interface, it is a completely new interface, its instance cannot be passed directly to the thread construct, so another interface is needed to convert it.
JAVA5 provides a future interface to represent the return value of the call () method in the callable interface, and provides an implementation class Futuretask for the future interface, which inherits from the implementation class:
It can be seen that the implementation class not only implements the future interface, but also implements the Runnable interface, so it can be passed directly to the thread constructor.
The constructor for Futuretask is as follows:
So this is actually more than the previous method of a conversion process, and ultimately the same as the start of thread to create a new thread. With this idea, the code is easy to understand:
Import java.util.concurrent.Callable;
Public class MyCallable implements Callable {
Int i = 0;
@Override
Public Object call() throws Exception {
System.out.println(Thread.currentThread().getName()+" The value of i: "+ i);
Return i++; //call method can have a return value
}
}
Test:
Import java.util.concurrent.Callable;
Import java.util.concurrent.FutureTask;
Public class Test {
Public static void main(String[] args) {
Callable callable = new MyCallable();
For (int i = 0; i < 10; i++) {
FutureTask task = new FutureTask(callable);
New Thread(task,"sub-thread"+ i).start();
Try {
/ / Get the return value of the child thread
System.out.println("Subthread return value: "+task.get() + "\n");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Execution results (partial):
4, the randomness of thread execution
The first method described above, said the order of execution of the thread is independent of the execution order of start (), but the CPU has a gap in the execution of the thread, so there is randomness, execution order is also random.
Example code:
public class MyThread extends Thread { int i; public MyThread(int i){ super(); this.i = i;
} @Override public void run(){
System.out.println(i);
}
}
Test code:
public class Test {
Thread thread1 = new MyThread(1);
Thread thread2 = new MyThread(2);
Thread thread3 = new MyThread(3);
Thread thread4 = new MyThread(4);
Thread thread5 = new MyThread(5);
Thread thread6 = new MyThread(6);
Thread thread7 = new MyThread(7);
Thread thread8 = new MyThread(8);
Thread thread9 = new MyThread(9);
Thread thread10 = new MyThread(10);
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread5.start();
thread6.start();
thread7.start();
thread8.start();
thread9.start();
thread10.start();
}
}
The results of the operation reflect this:
5, three different ways of comparison of the first and the following two kinds of comparison:
1, through the code can be seen, the first method is the most concise and convenient, directly can start, do not need any conversion
2, but the first one is a very bad place is inherited from the thread class because of the Java single Inheritance mechanism, you can not inherit other classes, and if the implementation is an interface, you can implement a number of interfaces, so that development more flexible.
The second and third way of comparison:
1, the same, the second method of the third way, the code is more concise, easier to use, less a conversion
2, the third method has two advantages: there is a return value, can throw an exception
Summarize
The actual development may have more complex code implementation, need to inherit other classes, so it is usually more recommended to implement the interface to implement multi-threading, that is, the second or third way to achieve, so that the code to maintain flexibility and decoupling.
The second or third option, depending on whether the run () method needs to return a value or catch an exception to decide, if not required, you can choose to implement the second way, the code is more concise.
Blog Park Address: Http://www.cnblogs.com/zivwong
CSDN Address: Blog.csdn.net/wannafly_z
Author personal website: Time Walk Z
Welcome, please give the source and link in obvious position