Java多线程(三) Thread和Runnable的基本用法

 一个线程对象生成后,如果要产生一个执行的线程,就一定要调用它的start()方法.在介绍这个方法时不得不同时说明run方法.其实线程对 象的run方法完全是一个接口回调方法,它是你这个线程对象要完成的具体逻辑.简单说你要做什么就你在run中完成,而如何做,什么时候做就不需要你控制 了,你只要调用start()方法,JVM就会管理这个线程对象让它产生一个线程并注册到线程处理系统中。

  从表面上看,start()方法调用了run()方法,事实上,start()方法并没有直接调用run方法.在JDK1.5以前 start()方法是本地方法,它如何最终调用run方法已经不是JAVA程序员所能了解的.而在JDK1.5中,原来的那个本地start()方法被 start0()代替,另个一个纯JAVA的start()中调用本地方法start0(),而在start()方法中做了一个验证,就是对一个全局变量 (对象变量)started做检验,如果为true,则start()抛出异常,不会调用本地方法start0(),否则,先将该变量设有true,然后 调用start0()。

  从中我们可以看到这个为了控制一个线程对象只能运行成功一次start()方法.这是因为线程的运行要获取当前环境,包括安全,父线程的权限, 优先级等条件,如果一个线程对象可以运行多次,那么定义一个static 的线程在一个环境中获取相应权限和优先级,运行完成后它在另一个环境中利用原来的权限和优先级等属性在当前环境中运行,这样就造成无法预知的结果.简单说 来,让一个线程对象只能成功运行一次,是基于对线程管理的需要。

start()方法最本质的功能是从CPU中申请另一个线程空间来执行 run()方法中的代码,它和当前的线程是两条线,在相对独立的线程空间运行,也就是说,如果你直接调用线程对象的run()方法,当然也会执行,但那是 在当前线程中执行,run()方法执行完成后继续执行下面的代码.而调用start()方法后,run()方法的代码会和当前线程并发(单CPU)或并行 (多CPU)执行。

  所以请记住一句话[调用线程对象的run方法不会产生一个新的线程],虽然可以达到相同的执行结果,但执行过程和执行效率不同。

实例如下:

package com.hisoft.threadrunnable;


 public class MyTRTest {


public static void main(String[] args) throws Exception {
// 10个线程对象产生的10个线程运行时打印了10次1
for (int i = 0; i < 10; i++) {
Thread t = new MyTThread();
t.start();
}
Thread.sleep(10000);
// 10个线程对象产生的10个线程运行时打印了1到10。我们把下面的10个线程称为同一实例(Runnable实例)的多个线程。
R r = new R();
for (int i = 0; i < 10; i++) {
Thread t = new Thread(r);
t.start();
}
}
 }


 class MyTThread extends Thread {
public int x = 0;


public void run() {
System.out.println("线程: " + Thread.currentThread().getName() + " 第 " + (++x) + "次执行此操作 ... ...");
}
 }


 class R implements Runnable {
private int x = 0;


public void run() {
System.out.println("线程: " + Thread.currentThread().getName() + " 第 " + (++x) + "次执行此操作 ... ...");
}
 }


执行结果如下:

线程: Thread-0 第 1次执行此操作 ... ...
线程: Thread-2 第 1次执行此操作 ... ...
线程: Thread-1 第 1次执行此操作 ... ...
线程: Thread-3 第 1次执行此操作 ... ...
线程: Thread-4 第 1次执行此操作 ... ...
线程: Thread-5 第 1次执行此操作 ... ...
线程: Thread-6 第 1次执行此操作 ... ...
线程: Thread-7 第 1次执行此操作 ... ...
线程: Thread-8 第 1次执行此操作 ... ...
线程: Thread-9 第 1次执行此操作 ... ...
线程: Thread-12 第 1次执行此操作 ... ...
线程: Thread-13 第 2次执行此操作 ... ...
线程: Thread-18 第 3次执行此操作 ... ...
线程: Thread-10 第 4次执行此操作 ... ...
线程: Thread-17 第 9次执行此操作 ... ...
线程: Thread-19 第 10次执行此操作 ... ...
线程: Thread-11 第 8次执行此操作 ... ...
线程: Thread-14 第 7次执行此操作 ... ...
线程: Thread-15 第 6次执行此操作 ... ...
线程: Thread-16 第 5次执行此操作 ... ...