1:Thread与Runnable的区别
Thread类是Runnable接口的实现类,Java中类只能单继承
Runnable是接口,可以多实现
2:是否在主线程中
new Thread开启一条子线程
new Runnable是否在子线程取决于当前调用的位置
3:线程与looper的关系
创建一个Runnable在主线程中,那该Runnable无需调用Looper(循环器)中的prepare()方法,可直接使用loop()方法去循环,使用的是主线程的Looper。
子线程中调用Runnable与创建一个Thread相同,那该Thread的Looper为null,如需要循环器要调用Looper.prepar();初始化Looper,可调用Looper.myLooper()获取Looper对象,Looper.loop();开启循环,使用Looper.myLooper().quit();结束循环,循环器慎用,在结束循环之前,Looper.loop();之后的代码将不会被执行。
4:run方法的执行
new Thread() {public void run(){}}.start();直接就会运行run方法在子线程中。
new Runnable(){public void run() {}};该Runnable的run方法需要调用才会执行。
new Thread(new Runnable() {public void run() {}}).start();会默认执行。
之所以会这样是Thread类中的start()方法会使此线程开始运行,虚拟机会调用run方法,如果是多条子线程拥有同样的优先级,cpu会快速在几个子线程中切换运行,而Runnable只是一个接口,其中只有一个抽象run方法,如果调用此run方法,而run方法没有执行完cpu不会切换到其它线程去执行
前面说过Thread实现于Runnable接口,我们来看一段Thread源码
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
上面这个构造方法就是例子中的第三个,这里最终调用的其实是还是Runnable的run方法,下方源码为证!
private Runnable target;
private void init(ThreadGroup g, Runnable target, String name,long stackSize, AccessControlContext acc) {
...
this.target = target;
...
}
@Override
public void run() {
if (target != null) {
target.run();
}
}
5:资源
多个Thread使用同一个Runnable的时候可以实现多线程中共享Runnable的资源,但是要避免脏数据的出现