通常创立线程应用两种形式
1.继承Thread类,重写run办法

public class ThreadDemo extends Thread {    @Override    public void run() {        System.out.println("创立线程形式1");    }    public static void main(String[] args) {        ThreadDemo threadDemo = new ThreadDemo();        threadDemo.start();    }    }

2.实现Runnable接口(Runnbale中只有一个run办法),重写run办法。而后把实例作为参数传入Thread的构造方法中

public class ThreadDemo implements Runnable {    @Override    public void run() {        System.out.println("创立线程形式2");    }    public static void main(String[] args) {        ThreadDemo threadDemo = new ThreadDemo();        //剖析源码        new Thread(threadDemo).start();    }}

3.剖析案例2中的源码得悉
1.Thread实现了Runnable接口,重写了run办法
2.threadDemo在构造函数中作为参数传递给Thread中的target属性
3.当执行线程的run办法时,target(threadDemo)执行子类重写的run办法,实现业务逻辑

public Thread(Runnable target) {    init(null, target, "Thread-" + nextThreadNum(), 0);}//只展现局部代码private void init(ThreadGroup g, Runnable target, String name,                  long stackSize, AccessControlContext acc,                  boolean inheritThreadLocals) {    if (name == null) {        throw new NullPointerException("name cannot be null");    }    this.name = name;        SecurityManager security = System.getSecurityManager();    this.group = g;      this.priority = parent.getPriority();      **this.target = target; ** }@Overridepublic void run() {    if (target != null) {        target.run();    }}

无论哪种形式创立线程,实质都是实现了Runnable接口,重写了run办法。间接调用run办法不属于多线程

Java线程的创立调用过程如上图所示。首先,Java线程的start办法会创立一个本地线程(通过调用JVM_StartThread),该线程的线程函数是定义在jvm.cpp中的thread_entry,由其再进一步调用run办法。能够看到Java线程的run办法和一般办法其实没有本质区别,间接调用run办法不会报错,然而却是在以后线程执行,而不会创立一个新的线程。

4.FutureTask,Callable,FutureTask也能够创立线程,并且能够取得返回值

FutureTask实现了Runnable接口重写run办法,同时能够作为参数传入Thread的构造函数。实现了Future接口,能够通过get(),cancel()获取返回值,勾销线程。

public class FutureTaskDemo implements Callable<String> {        @Override    public String call() throws Exception {        System.out.println("重写Callable中的call办法");        return "success";    }    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {        FutureTask task = new FutureTask(new FutureTaskDemo());                new Thread(task).start();        //获取返回值        System.out.println(task.get());    }    }

通过上面对Thread的剖析大抵, 在Thread中调用FutureTask的实例的run办法,而后run()中调用了Callable实例的call办法,执行业务逻辑。同时获取返回值。

援用文章:https://segmentfault.com/a/11...