The difference between Runnable and Thread in Java

Keywords: Java JDK jvm

There are two ways to implement multithreading in java, one is to inherit the Thread class, the other is to implement the Runnable interface; the Thread class is defined in the java.lang package. As long as a class inherits the Thread class and overrides the run() method in this class, it can achieve multithreading operation, but a class can only inherit a parent class, which is the limitation of this method.

Here's an example:

package org.thread.demo;  
class MyThread extends Thread{  
private String name;  
public MyThread(String name) {  
super();  
this.name = name;  
}  
public void run(){  
for(int i=0;i<10;i++){  
System.out.println("Threads start:"+this.name+",i="+i);  
}  
}  
}  
package org.thread.demo;  
public class ThreadDemo01 {  
public static void main(String[] args) {  
MyThread mt1=new MyThread("thread a");  
MyThread mt2=new MyThread("thread b");  
mt1.run();  
mt2.run();  
}  
} 

However, the results are very regular at this time. First, the first object executes, then the second object executes, and they do not run with each other. As you can see in the JDK documentation, once the start() method is called, the run() method is found through the JVM. Start the start() method to start the thread:

package org.thread.demo;  
public class ThreadDemo01 {  
public static void main(String[] args) {  
MyThread mt1=new MyThread("thread a");  
MyThread mt2=new MyThread("thread b");  
mt1.start();  
mt2.start();  
}  
}; 

  

In this way, the program can normally complete the interactive operation. So why use start(); method to start multithreading?

Under the JDK installation path, src.zip is the whole java source program. By finding the definition of start() method in Thread through this code, we can find that private native void start 0 () is used in this method. The native keyword indicates that the underlying function of the operating system can be invoked, so this technology becomes JNI technology (java Native Interface).

Runnable interface

In practical development, a multithreaded operation rarely uses the Thread class, but is accomplished through the Runnable interface.

public interface Runnable{  
public void run();  
} 

Example:

package org.runnable.demo;  
class MyThread implements Runnable{  
private String name;  
public MyThread(String name) {  
this.name = name;  
}
public void run(){  
for(int i=0;i<100;i++){  
System.out.println("Threads start:"+this.name+",i="+i);  
}  
}  
}; 

But there is no start() method in the subclass defined by Runnable, only in the Thread class. When you look at the Thread class, there is a constructor: public Thread(Runnable targer), which accepts instances of Runnable's subclasses, that is to say, the Thread class can be used to start multithreading implemented by Runnable. (start() coordinates system resources:

package org.runnable.demo;  
import org.runnable.demo.MyThread;  
public class ThreadDemo01 {  
public static void main(String[] args) {  
MyThread mt1=new MyThread("thread a");  
MyThread mt2=new MyThread("thread b");  
new Thread(mt1).start();  
new Thread(mt2).start();  
}  
} 

  

Differences and links between the two approaches:

In program development, as long as multithreading is always the main way to implement Runnable interface, because the implementation of Runnable interface has the following advantages compared with inheriting Thread class:

  • To avoid the limitation of point inheritance, a class can inherit multiple interfaces.
  • Suitable for resource sharing

Take the ticket selling program as an example, through the Thread class to complete:

package org.demo.dff;  
class MyThread extends Thread{  
private int ticket=10;  
public void run(){  
for(int i=0;i<20;i++){  
if(this.ticket>0){  
System.out.println("Selling tickets: ticket"+this.ticket--);  
}  
}  
}  
}; 

Following are three threaded objects that sell tickets at the same time:

package org.demo.dff;  
public class ThreadTicket {  
public static void main(String[] args) {  
MyThread mt1=new MyThread();  
MyThread mt2=new MyThread();  
MyThread mt3=new MyThread();  
mt1.start();//Each thread sells 10 tickets and 30 tickets.  
mt2.start();//But there are only 10 tickets, and each thread sells its own ticket.  
mt3.start();//Failure to achieve resource sharing  
}  
} 

If you can share resources with Runnable, here's an example:

package org.demo.runnable;  
class MyThread implements Runnable{  
private int ticket=10;  
public void run(){  
for(int i=0;i<20;i++){  
if(this.ticket>0){  
System.out.println("Selling tickets: ticket"+this.ticket--);  
}  
}  
}  
}  
package org.demo.runnable;  
public class RunnableTicket {  
public static void main(String[] args) {  
MyThread mt=new MyThread();  
new Thread(mt).start();//The same mt,But in Thread No, if you use the same one.  
new Thread(mt).start();//Instance objects mt,There will be anomalies.  
new Thread(mt).start();  
}  
}; 

Although there are three threads in the program, 10 tickets have been sold, that is to say, using Runnable to achieve multi-threading can achieve the purpose of resource sharing.

The connection between the Runnable interface and Thread:

public class Thread extends Object implements Runnable

It is found that the Thread class is also a subclass of the Runnable interface.

Posted by sandrob57 on Wed, 27 Mar 2019 01:27:30 -0700