一、Thread VS Runnable
In java there are two ways to achieve multi-threading, one is a Thread class inheritance, one is to achieve Runnable interface; Thread class and Runnable interface are defined in the java.lang package. Then the author describes the differences to you under the Java Runnable and Thread of course, I also counted as study notes finishing it, look at it
- Implement Runnable way to avoid inherited defect Thread way because the Java single inheritance feature brings. What specific defects it?
① First, to achieve distinction and class inherits from the interface to talk
If you want to write a C class, but the class C has inherited a class A, at this time, and you want to achieve multi-threaded C. Thread class inheritance to die the way. (Because of the limitations of single inheritance), at this time, can only use the Runnable interface, the interface Runnable is to solve this situation arise
② from the implementation mechanism Thread and Runnable's come to talk about this issue
First Thread
and Runnable
implementation is actually a static proxy. We can simply look at the source code to understand:
public interface Runnable {
public abstract void run(); } public class Thread implements Runnable { ... private Runnable target; public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0); } public void run() { if (target != null) { target.run(); //代理的target的run方法 } } }
We know that another thread started calling thread.start()
method, but the start()
method calls native
the start0()
method, then the JVM
controls to achieve the control multithreading, because the system needs to call time slicing.
Now we can look deep understanding of similarities and differences in the thread implementation.
Class MyThread extends Thread(){
public int count = 10; public synchronized void run(){ while(count>0){ count--; } } } new Mythread().start(); //启动 n 个线程 new Mythread().start();
This implementation is actually a rewrite run()
method, due to resource and thread Thread
instance bundled together, so different threads of resources will not be shared.
Class MyThread implements Runnable{
public int count = 10;
public synchronized void run(){ while(count>0){ count--; } } } MyThread mt = new MyThread(); new Thread(mt).start(); //启动 n 个线程 new Thread(mt).start();
This implementation is a static proxy way, the thread resources and Runable
examples bundled together, Thread
just as a proxy class, so resources can be shared.
③ from the Java
language designer's point of view
Runnable
It can be understood as Task
, corresponds to the specific tasks to be run, but Thread
one particular thread running corresponding carrier. In summary, inheritance Thread
is implemented, it can be said is not recommended.
Runnable code implementation may be a plurality of threads (Thread example) share a plurality of threads adapted to process the same resource.
The following typical procedures tickets to illustrate this point (I'm here, do not use synchronized synchronized block, the results will not likely run in order to allow us to understand the normal cards):
① to achieve through inheritance Thread
Package me.demo.thread. 1; 2 . 3 the MyThread the extends the Thread class { . 4 Private ticketsCont = int. 5; // a total of five tickets 5 private String name; // window, that is, the name of the thread . 6 . 7 the MyThread public ( name String) { . 8 this.name = name; . 9} 10 . 11 @Override 12 is public void RUN () { 13 is the while (ticketsCont> 0) { 14 ticketsCont--; // if there is a ticket to sell 15 System. out.println (name + "Buy a ticket, the remaining votes is:" + ticketsCont); 16} . 17} 18 is} . 19 20 is TicketsThread {public class 21 is 22 is public static void main (String [] args) { 23 is // create three threads to simulate three ticket windows 24 MyThread mt1 = new MyThread ( "window. 1"); 25 = MT2 the MyThread the MyThread new new ( "window 2"); 26 is the MyThread the MyThread MT3 new new = ( "window 3"); 27 28 // three start thread, and That is the window start ticket 29 mt1.start (); 30 mt2.start (); 31 is mt3.start (); 32} 33 is}
We run this program will find three threads each bought five tickets, bought a total of 15 tickets, we simulate the train station window to a total of only five votes, which obviously wrong ah, but do not On the sharing of resources, because the program, we create an instance of an object three MyThread, as ticketsCont ordinary member variables (note that this non-static member variables, static member variables if it is another matter) apparently is initialized three times, exist in three different objects, so it caused this result, showing that Thread is not suitable for resource sharing.
② be achieved by implementing Runnable interface:
Package me.demo.runnable. 1; 2 . 3 the MyThread the implements the Runnable {class . 4 . 5 Private ticketsCont = int. 5; // a total of five tickets . 6 . 7 @Override . 8 public void RUN () { . 9 the while (ticketsCont> 0) { 10 ticketsCont -; // if there is a ticket sold to 11 System.out.println (Thread.currentThread () getName ( ) + " Buy a ticket, the remaining votes as:" ticketsCont +.); 12 is} } 13 is 14 15} 16 . 17 {public class TicketsRunnable 18 is . 19 public static void main (String [] args) { 20 is the MyThread the MyThread new new thread = (); 21 is // create three threads to simulate three wickets 22 thread th1 = new Thread (thread, "a window"); 23 thread th2 = new Thread (thread, "window 2"); 24 = the Thread new new TH3 the Thread (Thread, "window 3"); 25 26 is started // these three threads, that is, three window start ticket 27 th1.start (); 28 th2.start (); 29 th3.start (); 30} 31 is}
We run this program found that a total of three Thread sell five tickets, it is clearly in the case of daily life, because Thread to achieve a shared instance of the class member variables MyThread Runnable interface ticketsCont, the above problem does not exist a.
In addition, for the above code to add three points:
-
In the second method (Runnable), the order of ticket 54321 is not output, because the timing of thread execution is difficult to predict, ticket-- not atomic operations.
-
In the first method, we have three new Thread object, that is, three threads are executing code three objects, and therefore is three threads to complete the task of selling tickets independently; while in the second method we also three new thread object, but only one Runnable object 3 thread object code sharing this Runnable object, therefore, the result of three threads together to complete the task of selling tickets will appear. If we are out of three new Runnable objects as parameters are passed in 3 Thread object, then the three will be independent threads to execute code each Runnable object, that is, three threads each sell 5 tickets.
-
In the second method, since 3 Thread objects together to execute code in a Runnable object, and therefore may cause an unsafe threads, such as ticket may be output 1 (before the statement added if we System.out .... the thread sleep operation, the case is likely to occur), this situation is due, a ticket is judged thread 1> 0, 1 have not had time Save, Save another thread has the ticket 1, becomes a 0, then the ticket before the next thread and then subtract 1, get a -1. This requires the addition of synchronization (ie, mutex) to ensure that only one thread to perform the operation for each cycle. In the first method, it is not necessary to add synchronization, each thread executing code own Thread object, performing a plurality of threads together with the absence of the method.
Second, summary
Thread class is a subclass of Runnable interface, we can see, implement Runnable relative to inherit the Thread class, the following significant benefits:
-
Case for multiple threads of the same program code to deal with the same resources, the code virtual CPU (threads) with program data effective separation, to better reflect the object-oriented design.
-
Java can be avoided due to the limitations of single inheritance feature brings. We often encounter such a situation, that is when we want to have inherited a subclass of a class into multiple threads, as a parent class can not have two classes at the same time, so the way to inherit the Thread class is not available, then this class can only be achieved by way of the Runnable interface.
-
In favor of program robustness, code can be shared by multiple threads, code and data are independent. When a plurality of threads executing the code from the same instance of a class, said i.e. they share the same code. A plurality of threads operating the same data, regardless of their codes. When the same object is a shared access, i.e. they share the same data. When a thread is configured, as required code and data into the constructor arguments passed through an object, this object is an instance of a class implements Runnable interface.
Reprinted to https://www.cnblogs.com/albertrui/p/8380017.html