Thread, Runnable, callable, future, Futuretask of multithreaded series
Preface
Multi-Threading has always been a beginner's most contradictory thing, if you want to advanced, that must go through this difficulty, especially in multi-threading thread, Runnable, callable, future, futuretask these classes are often beginner easy to confuse. here to summarize the characteristics and differences of these categories, so that people with a vague impression to learn this article
- Thread, Runnable, callable: All Threads
- Thread Features: Provides threading wait, thread sleep, thread comity, and other operations
- Runnable and callable features: both are interfaces and provide the corresponding implementation method
- Runnable, callable difference: Runnable No return value, callable has return value
- Future: Provides actions to cancel the execution of runnable and callable tasks, query completion, get results, set results, and more
- The combination of futuretask:runnable and future, the characteristic of the future
This article contains the following content
- The relationship between thread and runnable
- The difference between runnable and callable
- Future
- Futuretask
the relationship between thread and runnable
Our use of threads is often written in these two ways
new Thread(new Runnable() { @Override publicvoidrun() { //子线程操作 }}).start();new Thread(){ @Override publicvoidrun() { //子线程操作 }}.start();
This is what we want to talk about the thread and runnable relationship, in fact, they are the same, are threads, eventually start the thread will execute the run () method inside the content, specifically, let us start from the thread source code analysis
class Thread implements Runnable { PrivateRunnable Target;//Constructors PublicThread (ThreadgroupGroup, Runnable target) {init (Group, Target,"thread-"+ Nextthreadnum (),0); }//Continue to track the Init () method Private voidInit (Threadgroup g, Runnable Target, String name,LongStackSize) {Thread parent = CurrentThread ();if(g = =NULL) {g = Parent.getthreadgroup (); } g.addunstarted (); This.Group= g; This. target = target; This. Priority = Parent.getpriority (); This. Daemon = Parent.isdaemon (); SetName (name); Init2 (parent);/ * Stash The specified stack size in case the VM cares * / This. stackSize = stackSize; Tid = Nextthreadid (); }}
You can see that thread is the implementation of runnable, so thread can also be said to be runnable, they are like their own brothers. Since the first step when creating a thread is the new thread (), so seeing the thread's constructor and continuing to trace, you will find that if a runnable is passed in, it will be given a member variable of target. And Target is a runnable. Next, call the thread's start () method, and we look at the source of the start () method
Public synchronized void Start() {if(Threadstatus! =0)Throw NewIllegalthreadstateexception (); Group.add ( This); started =false;Try{//Finally call this methodNativecreate ( This, stackSize, daemon); started =true; }finally{Try{if(!started) {group.threadstartfailed ( This); } }Catch(Throwable ignore) { } }}//Continue tracking Nativecreate () methodPrivate native Static void nativecreate(Thread T,LongStackSize,Booleandaemon);
We can see that the start () method is called at the end of the local Nativecreate () method, which is a bold guess, which should be the run () method inside the thread, because after we open the thread, the thread will always execute the contents of the run (). So this should be the run () method that called the thread. We look at the source code of the Run () method
@Overridepublicvoidrun() { ifnull) { target.run(); }}
Here, the task that is actually ultimately executed by the thread is runnable, not thread,thread, just the runnable wrapper. Executes the target's run () method if Target is not empty, otherwise executes the run () method of the current object
the difference between runnable and callable
Runnable and callable are also threads, and their differences can be seen from their source code, the following is the source of runnable and callable
publicinterface Runnable { publicabstractvoidrun();}@FunctionalInterfacepublicinterface Callable<V> { V call() throws Exception;}
It can be found that callable has a return value of a generic type, and runnable does not return a value, so using callable can return the result of the thread, and runnable not
Future
The future is not a thread, it can be understood as a management thread of the person, but it is not a lot of management methods of threading, this can be seen from the future source, the following is the future of the source
publicinterface Future<V> { //取消任务 boolean cancel(boolean mayInterruptIfRunning); //该任务是否已经取消 boolean isCancelled(); //该任务是否已经完成 boolean isDone(); //获取任务的返回结果,该方法会阻塞线程 get() throws InterruptedException, ExecutionException; //获取任务的返回结果,该方法会阻塞线程 get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;}
Intervention do not practice fake bashi, we understand by example, here threads we all use the thread pool to execute, if the thread pool does not understand, you can view my blog Android advanced-multi-threaded series of four thread pool usage introduction
Public class threadactivity extends appcompatactivity {@Overrideprotected voidOnCreate (Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate); Setcontentview (R.layout.activity_thread);//thread poolExecutorservice executor = Executors.newfixedthreadpool (Ten);//First step: Create a threadMyrunnable myrunnable =NewMyrunnable (); Mycallable mycallable =NewMycallable ();Try{//Second step: Execution thread with return valuefuture<integer> callablefuture = Executor.submit (mycallable);the//get () method causes the thread to blockSystem.out.println ("Callablefuture Gets the result:"+ Callablefuture.get ()); System.out.println ("Callablefuture iscancelled (whether canceled):"+ callablefuture.iscancelled ()); System.out.println ("Callablefuture IsDone (whether completed):"+ Callablefuture.isdone ());//Step Two: Execution thread has no return valuefuture<?> runnablefuture = Executor.submit (myrunnable); System.out.println ("Runnablefuture Gets the result:"+ Runnablefuture.get ()); System.out.println ("Runnablefuture iscancelled (whether canceled):"+ runnablefuture.iscancelled ()); System.out.println ("Runnablefuture IsDone (whether completed):"+ Runnablefuture.isdone ()); }Catch(Interruptedexception e) {E.printstacktrace (); }Catch(Executionexception e) {E.printstacktrace (); } } Public class myrunnable implements Runnable {@Override Public voidRun () {System.out.println ("I'm runnable."); } } Public class mycallable implements callable<Integer> { @Override PublicInteger call () throws Exception {System.out.println ("I'm callable.");return Ten; } }}
The first step: Create thread mycallable is implemented callable, the generic type is filled with the return value, and runnable is not
The second step: through the thread pool executor submit thread, return the corresponding future<?> object, if there is a return value to fill in the return value type, if no return value is filled? No.
Let's look at the results of the future management class by printing the information , once again proving that the difference between runnable and callable
我是CallableCallableFuture获取的结果:10CallableFuture isCancelled(是否已经取消):falseCallableFutureisDone(是否已经完成):true我是RunnableRunnableFuture获取的结果:nullRunnableFuture isCancelled(是否已经取消):falseRunnableFuture isDone(是否已经完成):true
Futuretask
Futuretask is the realization of the future class, and not only the future is runnable, but also the packaging of callable, it is the combination of the two. From the source of Futuretask can be seen
//Continue tracking Runnablefuture Public class futuretask<v> implements runnablefuture<V > { //Construction method PublicFuturetask (callable<v> callable) {if(Callable = =NULL)Throw NewNullPointerException (); This. callable = callable; This. state = NEW; }//Construction method PublicFuturetask (Runnable Runnable, V result) { This. callable = executors.callable (runnable, result); This. state = NEW; }}
//RunnableFuture继承Runnable、Futurepublicinterface RunnableFuture<V> extends Runnable, Future<V> { void run();}
The source code can be seen in the constructor need to pass in a callable or runnable, if passed in is a runnable will be executors.callable () converted to callable type of task, That is, Futuretask is ultimately a task that performs the callable type. Continue tracking Executors.callable ()
//executors.callable () method Public Static<T> callable<t> Callable (Runnable task, T result) {if(Task = =NULL)Throw NewNullPointerException ();return NewRunnableadapter<t> (task, result);}//Continue tracking Runnableadapter<t> classPrivate Static Final class runnableadapter<t> implements callable<t > { Private FinalRunnable task;Private FinalT result; Runnableadapter (Runnable task, T result) { This. task = task; This. result = result; } PublicT call () {task.run ();returnResult }}
Because Futuretask implements the runnable, it can either be run directly through the thread wrapper, or it can be executed by the Executeservice, and it can get the execution result through the Get () method, which blocks until the result is returned. Here's a simple example to illustrate the use of futuretask
Public class futuretaskactivity extends appcompatactivity {@Overrideprotected voidOnCreate (Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate); Setcontentview (R.layout.activity_future_task);//thread poolExecutorservice executor = Executors.newfixedthreadpool (Ten);//Create threadMycallable callable =NewMycallable ();//Wrapper threadFuturetask<string> Futuretask =NewFuturetask<string> (callable);//Execution threadExecutor.submit (Futuretask);//Get Results Try{System.out.println (Futuretask.get ()); }Catch(Interruptedexception e) {E.printstacktrace (); }Catch(Executionexception e) {E.printstacktrace (); } } Public class mycallable implements callable<String> {@Override PublicString call () throws Exception {Thread.Sleep ( -);return "I am the callable return value"; } }}
Its printing information is
我是Callable返回值
Well, this chapter is introduced here, for multi-threaded development still need a lot of practice to really understand its practical significance, more multi-threaded learning can follow my blog
Android Advanced-Multithreading series of Thread, Runnable, callable, future, Futuretask