1) runnable and callable are the same interface
* Callable's task can return a value after execution, and Runnable's task is not to return a value (is void); The call method can throw an exception, and the Run method cannot
* Run the callable task to get a future object that represents the result of an asynchronous calculation. It provides a way to check whether the calculation is complete, to wait for the completion of the calculation, and to retrieve the results of the calculation. The future object enables you to understand task execution, cancel the execution of a task, and get execution results.
* Join thread pool run, runnable use Executorservice's Execute method, callable use the Submit method.
2) thread class and Runnable interface
Java-based single inheritance restriction, the first difference between the two:
* Avoid the limitations of Java single inheritance
* Runnable interface can automatically realize the sharing of resources, for the thread class, if you want to implement sharing, you need to change the shared resources to static resources. This is illustrated by the example of a ticket sales case, as follows:
Inherit the thread class
1 classextendsthreadextends thread{2 Private intTicket = 5;3 PrivateString name;4 PublicFirstthread (String name) {5 This. Name =name;6 }7 Public voidrun () {8 for(inti=0;i<10;i++){9 if(Ticket > 0){TenSystem.out.println ("Inherit thread-->" +name + "sell ticket:" + (ticket--)); One } A } - } - } the Public classInitthread { - Public Static voidMain (string[] args) { - NewExtendsthreadextends ("window number One")). Start (); - NewExtendsthreadextends ("Window No. Second"). Start (); + NewExtendsthreadextends ("Window No. Third"). Start (); - } +}
View Code
Output
Implementing the Runnable Interface
1 classSecondthreadImplementsrunnable{2 Private intTicket = 5;3 @Override4 Public voidrun () {5 for(inti=0;i<10;i++){6 if(Ticket > 0){7System.out.println ("Implement runnable-->" + Thread.CurrentThread (). GetName () + "sell ticket:" + (ticket--));8 }9 }Ten } One A } - - Public Static voidMain (string[] args) { theSecondthread Secondthread =NewSecondthread (); - NewThread (secondthread, "window number One")). Start (); - NewThread (secondthread, "window number second"). Start (); - NewThread (secondthread, "window number Third"). Start (); + -}
View Code
Output
1. The first of the above new 3 thread objects, you can see the equivalent of three independent threads in the execution of the ticket sales task, the second is new 3 objects, but only a Runnable object, 3 thread share the code of this Runnable object, As a result, three threads were executed together to perform the ticket sales task. If new 3 runnable objects are executed, there will also be 3 threads selling 5 tickets on their own.
2. The second is to achieve the purpose of resource sharing, if you want the first to achieve the second effect, then change the ticket variable to static, so that the resource sharing is relative.
3. Resource sharing is designed to be a thread-safe issue, and ticket--operations are not atomic. Ticket is possible to output negative numbers in System.out ... Preceded by a thread hibernation operation, the following results appear:
When ticket=1, window one executes to ticket>0, window two executes to ticket--, at this time ticket is already 0, but the window three or one thread still will carry on ticket--operation, cause output ticket to 0, even negative.
To solve this problem, you need to introduce a thread synchronization operation that is a mutex.
"Multi-threaded learning record One (2)" inherits the thread class and implements the difference between the Runnable interface and the callable interface