关于线程thread和runnable

Runnable的意思是,你要用代码——也就是run( )方法——来描述一个处理过程,而不是创建一个表示这个处理过程的对象。在如何理解线程方面,一直存在着争议。这取决于,你是将线程看作是对象还是处理过程[68]。如果你认为它是一个处理过程,那么你就摆脱了"万物皆对象"的OO教条。但与此同时,如果你只想让这个处理过程掌管程序的某一部分,那你就没理由让整个类都成为Runnable的。有鉴于此,用内部类的形式将线程代码隐藏起来,通常是个更明智的选择。就像下面这段代码:

//: c13:ThreadVariations.java
// Creating threads with inner classes.
import com.bruceeckel.simpletest.*;
// Using a named inner class:
class InnerThread1 {
private int countDown = 5;
private Inner inner;
private class Inner extends Thread {
Inner(String name) {
super(name);
start();
}
public void run() {
while(true) {
System.out.println(this);
if(--countDown == 0) return;
try {
sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public String toString() {
return getName() + ": " + countDown;
}
}
public InnerThread1(String name) {
inner = new Inner(name);
}
}
// Using an anonymous inner class:
class InnerThread2 {
private int countDown = 5;
private Thread t;
public InnerThread2(String name) {
t = new Thread(name) {
public void run() {
while(true) {
System.out.println(this);
if(--countDown == 0) return;
try {
sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public String toString() {
return getName() + ": " + countDown;
}
};
t.start();
}
}
// Using a named Runnable implementation:
class InnerRunnable1 {
private int countDown = 5;
private Inner inner;
private class Inner implements Runnable {
Thread t;
Inner(String name) {
t = new Thread(this, name);
t.start();
}
public void run() {
while(true) {
System.out.println(this);
if(--countDown == 0) return;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public String toString() {
return t.getName() + ": " + countDown;
}
}
public InnerRunnable1(String name) {
inner = new Inner(name);
}
}
// Using an anonymous Runnable implementation:
class InnerRunnable2 {
private int countDown = 5;
private Thread t;
public InnerRunnable2(String name) {
t = new Thread(new Runnable() {
public void run() {
while(true) {
System.out.println(this);
if(--countDown == 0) return;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public String toString() {
return Thread.currentThread().getName() +
": " + countDown;
}
}, name);
t.start();
}
}
// A separate method to run some code as a thread:
class ThreadMethod {
private int countDown = 5;
private Thread t;
private String name;
public ThreadMethod(String name) { this.name = name; }
public void runThread() {
if(t == null) {
t = new Thread(name) {
public void run() {
while(true) {
System.out.println(this);
if(--countDown == 0) return;
try {
sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public String toString() {
return getName() + ": " + countDown;
}
};
t.start();
}
}
}
public class ThreadVariations {
private static Test monitor = new Test();
public static void main(String[] args) {
new InnerThread1("InnerThread1");
new InnerThread2("InnerThread2");
new InnerRunnable1("InnerRunnable1");
new InnerRunnable2("InnerRunnable2");
new ThreadMethod("ThreadMethod").runThread();
monitor.expect(new String[] {
"InnerThread1: 5",
"InnerThread2: 5",
"InnerThread2: 4",
"InnerRunnable1: 5",
"InnerThread1: 4",
"InnerRunnable2: 5",
"ThreadMethod: 5",
"InnerRunnable1: 4",
"InnerThread2: 3",
"InnerRunnable2: 4",
"ThreadMethod: 4",
"InnerThread1: 3",
"InnerRunnable1: 3",
"ThreadMethod: 3",
"InnerThread1: 2",
"InnerThread2: 2",
"InnerRunnable2: 3",
"InnerThread2: 1",
"InnerRunnable2: 2",
"InnerRunnable1: 2",
"ThreadMethod: 2",
"InnerThread1: 1",
"InnerRunnable1: 1",
"InnerRunnable2: 1",
"ThreadMethod: 1"
}, Test.IGNORE_ORDER + Test.WAIT);
}
} ///:~
InnerThread1创建了一个继承Thread的非匿名内部类,然后在构造函数里创建了一个这个内部类的实例。如果你要用宿主类的方法访问内部类的特殊功能(新方法)的话,这种做法会比较好。但是绝大多数情况下,创建线程的目的,只是要用它的Thread功能,所以不必创建非匿名的内部类。InnerThread2就演示了这个方案:在构造函数里面创建一个继承Thread的匿名内部类,然后把它上传给Thread的reference t。宿主类的其它方法可以通过t访问Thread的接口,它们无需知道这个对象的确切类型。

第三和第四个类重复了前两个类,不过它们都不是Thread,而是Runnable。这么做是想告诉你,用Runnable什么便宜也没占到,相反代码还稍微复杂了一些(也更难读了一些)。所以结论是,除非迫不得已只能用Runnable,否则我会选Thread。

ThreadMethod演示了怎样在方法的内部创建线程。要运行线程的时候就调用方法,线程启动之后方法就返回。如果这个线程不那么重要,只是做一些辅助操作的话,那么相比在构造函数里启动线程,这个方法或许会更好一些
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值