JAVA中Thread VS Runnalbe

来源:互联网 发布:人工智能语音电话 编辑:程序博客网 时间:2024/06/03 21:45

JAVA中创建线程有两种方式, 直接继承Thread或者实现Runnable接口,然后将Runnable实现类对象传入Thread.
本篇讨论的内容:

一,Thread和Runnable的关系
二, 创建线程的使用过程中,Thread和Runnable的选择?

=========================
一,Thread和Runnable的关系
我们实现线程的时候会考虑到通过实现Runnable接口,然后将实现了这个接口的实例传递给Thread的构造函数,然后开启线程.那么我们看看Runnable到底是个什么东西?

public interface Runnable {    public abstract void run();}

我们可以发现Runnable接口就是一个简单的接口, 里面一个抽象的Runable方法. 他怎么和线程关联呢? 那我们就进入Thread类看看

首先,我们可以发现在Thread中有一个Runnable类型的成员变量target

   .............. /* What will be run. */    private Runnable target;    ..............

再继续向下看

 public Thread(Runnable target) {        init(null, target, "Thread-" + nextThreadNum(), 0);    }
 private void init(ThreadGroup g, Runnable target, String name,                      long stackSize) {     .........        this.group = g;        this.daemon = parent.isDaemon();        this.priority = parent.getPriority();        this.name = name.toCharArray();        if (security == null || isCCLOverridden(parent.getClass()))            this.contextClassLoader = parent.getContextClassLoader();        else            this.contextClassLoader = parent.contextClassLoader;        this.inheritedAccessControlContext = AccessController.getContext();        //复制给成员变量target        this.target = target;        setPriority(priority);        if (parent.inheritableThreadLocals != null)            this.inheritableThreadLocals =                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);        /* Stash the specified stack size in case the VM cares */        this.stackSize = stackSize;        /* Set thread ID */        tid = nextThreadID();    }

我们可以看到,使用Thread(Runnable target),然后调用init方法,检查线程初始化的条件是否满足,设置线程名字,线程编号等等,又把传递过来的target对象传递给Thread的成员变量

    @Override    public void run() {        if (target != null) {            target.run();        }    }

然后在线程的run方法中,判断target对象是否为空,若不为空,那么Thread就执行了Runnable中的run()方法内容.

由上面我们可以提出问题为什么java中提供继承Thread类和实现Runnable方法两种方式创建线程呢? 在这里我们可以猜测,主要是由于java的继承体系只支持单继承,为了扩展和使创建线程的方式更加灵活,就又增加了使用Runnable 接口方式

二, 创建线程的使用过程中,Thread和Runnable的选择?
1,java不支持多继承,如果继承Thread类实现线程,意味着你将失去机会扩展或者继承其他类了

2,在面向对象的编程中,继承一个类通常意味着增加新的功能,或者修改和提升改善类的行为(方法).如果没有这些需求那就选择Runnable

3,Runnable接口通常代表一个可以被Thread,Executers或者其他方式执行的一个实例,如果考虑到任务的逻辑奋力使用Runnable更好一些

4,任务分离的Runnable可以重用任务和更自由的被其他方式进行执行. 一个Thread执行完毕后不会被重启

第二部分参考查阅: http://javarevisited.blogspot.com/2012/01/difference-thread-vs-runnable-interface.html#ixzz3Y3UtwTQx

0 0