java并发编程(一)
线程基础
在Java代码中,单独创建线程,都需要使用类java.lang.Thread,通常可以通过集成并扩展Thread的run()方法,也可以来创建一个Thread,将一个Runnable任务实体当做参数传入,这是通过线程来执行任务的过程,但并不能说实现了Runnable接口就是一个线程。
Runnable接口,就是“可以被执行”的意思。例如:Closeable。它只能代表“可以被关闭”,Closeable接口中描述中提供了一个close()方法要求子类实现。
一个线程的启动需要Thread通过Thread.start()方法来完成,这个方法需要调用本地方法(JNI)来实现真正意义上得线程,或者说只有start()成功调用后由OS分配线程资源,才能叫做线程,而在JVM中分配的Thread对象只是与之对应的的外壳。
Runbable既然不是线程,有什么用呢?
如何区分继承Thread实现start()来完成线程的实现与实现Runnable接口的run()方法,放入Thread调用start()方法进行执行。
可以将Runnable看成一个“任务”,在与Thread配合使用,即在创建线程的时候将Runnable的实例化对象作为参数传入。此时,Runnable的实例化对象将被设置到Thread所在对象中的一个名为“traget”的属性上,Thread默认的run()方法是调用这个target的run()方法来完成的,这样的Runnable的概念就和线程区分开来。Runnable本身是任务,线程可以执行任务
Thread需要通过子类去实现run()方法来描述任务的内容。
同时,一个Thread可以尝试获取多个Runnable任务,每次获取之后进行执行run()方法。这样就能明确区分Thread和Runnable不是一个概念。
/**
* @author cc
* @date 2016年7月1日 下午5:01:26
*/
public class Demo {
public static void main(String[] args) {
new Thread(){
@Override
public void run() {
System.out.println("我是新创建的线程,我执行了......");
};
}.start();
System.out.println("我是主线程,我执行结束了");
}
}
如果顺序执行,理应先输出“我是新创建的线程,我执行了......”,然后输出“我是主线程,我执行结束了”(因为代码顺序是这样的)。但是大家测试过之后,一般情况下,结果恰恰相反。其实原因很简单,当一个线程被创建的时候,需要OS重新调用资源才会创建,整个创建过程需要时间;在此时,主线程已经往后执行,已经输出了内容。
参考:《Java特种兵(上册)》--谢宇编著