Java创建线程(Runnable接口和Thread类)

    |     2015年4月13日   |   多线程编程   |     0 条评论   |    1473

多数情况通过实例化一个 Thread 对象来创建线程。Java 定义了两种方式:实现 Runnable 接口,或继承 Thread 类。

方式 入口 适用
implements Runnable new Thread(this, name) 再 start() 不必改 Thread 其他方法时优先
extends Thread super(name) 后 start(),重写 run() 确实要增强 / 修改 Thread 时

一、实现 Runnable

最简单的办法是写一个实现 Runnable 的类。Runnable 抽象了一个执行代码单元。只需实现 public void run()。run 里可以像主线程一样调其他方法、引用其他类、声明变量;唯一不同是它确立了另一条并发入口。run 返回,该线程结束。

然后在类里实例化 Thread。常用构造函数:Thread(Runnable threadOb, String threadName)。新线程建好后并不会跑,直到调用 void start()——本质上 start 会去调 run。

// Create a second thread.
class NewThread implements Runnable {
    Thread t;
    NewThread() {
        t = new Thread(this, "Demo Thread");
        System.out.println("Child thread: " + t);
        t.start();
    }
    public void run() {
        try {
            for (int i = 5; i > 0; i--) {
                System.out.println("Child Thread: " + i);
                Thread.sleep(500);
            }
        } catch (InterruptedException e) {
            System.out.println("Child interrupted.");
        }
        System.out.println("Exiting child thread.");
    }
}

class ThreadDemo {
    public static void main(String args[]) {
        new NewThread();
        try {
            for (int i = 5; i > 0; i--) {
                System.out.println("Main Thread: " + i);
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            System.out.println("Main thread interrupted.");
        }
        System.out.println("Main thread exiting.");
    }
}

构造函数里 new Thread(this, "Demo Thread") 表示新线程要调 this 上的 run。start 之后构造函数返回 main,主线程进入自己的 for。两条线程共享 CPU,直到各自循环结束。典型输出:

Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Main Thread: 4
Child Thread: 3
Child Thread: 2
Main Thread: 3
Child Thread: 1
Exiting child thread.
Main Thread: 2
Main Thread: 1
Main thread exiting.

多线程里通常主线程应最后结束。一些老 JVM 若主线程先于子线程结束,运行时可能“挂起”。本例主线程 sleep 1000ms、子线程 500ms,保证子线程先完。后面会讲更好的等待方式(join)。

二、扩展 Thread

另一个途径是新建类扩展 Thread,再创建实例。必须重载 run 作为入口,并调用 start 启动。用 super("Demo Thread") 调用 public Thread(String threadName)。

class NewThread extends Thread {
    NewThread() {
        super("Demo Thread");
        System.out.println("Child thread: " + this);
        start();
    }
    public void run() {
        try {
            for (int i = 5; i > 0; i--) {
                System.out.println("Child Thread: " + i);
                Thread.sleep(500);
            }
        } catch (InterruptedException e) {
            System.out.println("Child interrupted.");
        }
        System.out.println("Exiting child thread.");
    }
}

class ExtendThread {
    public static void main(String args[]) {
        new NewThread();
        try {
            for (int i = 5; i > 0; i--) {
                System.out.println("Main Thread: " + i);
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            System.out.println("Main thread interrupted.");
        }
        System.out.println("Main thread exiting.");
    }
}

输出与前一版相同。子线程由实例化 NewThread(派生自 Thread)生成。

三、选哪一种

Thread 定义了多种可被派生类重载的方法,但必须重载的只有 run——这也是 Runnable 要求的那一个。很多 Java 程序员认为:类只在被加强或修改时才应该被扩展。因此若不重载 Thread 的其他方法,最好只实现 Runnable。本章其余部分用实现 Runnable 的类来创建线程。

一句话总结:run 写线程体,start 才启动;能实现 Runnable 就别去继承 Thread,主线程用更长的 sleep(或后面的 join)保证最后退出。

转载请注明来源:Java创建线程(Runnable接口和Thread类)
本文链接地址:https://ai.zhousir.top/?p=211

上一篇:

下一篇:

回复 取消