Java multi-threading of Thread and Runnable

一、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

Copy the code
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}
Copy the code

  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:

Copy the code
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}
Copy the code

  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

Guess you like

Origin www.cnblogs.com/yisong-china/p/12171972.html