从我在Java中使用线程的时间来看,我发现了两种编写线程的方法:
使用可运行的机具:
public class MyRunnable implements Runnable {
public void run() {
//Code
}
}
//Started with a "new Thread(new MyRunnable()).start()" call
或者,使用扩展线程:
public class MyThread extends Thread {
public MyThread() {
super("MyThread");
}
public void run() {
//Code
}
}
//Started with a "new MyThread().start()" call
这两个代码块有什么显著的区别吗?
随着Java8的发布,现在有了第三个选项。
Runnable是一个函数接口,这意味着可以使用lambda表达式或方法引用创建它的实例。
您的示例可以替换为:
new Thread(() -> { /* Code here */ }).start()
或者如果要使用ExecutorService和方法引用:
executor.execute(runner::run)
这些不仅比示例要短得多,而且还具有其他答案中所述的使用Runnable over Thread的许多优点,例如单一责任和使用组合,因为您没有专门处理线程的行为。如果您只需要一个Runnable,那么这种方法也可以避免创建一个额外的类。
线程保持不打算访问的行为;
它的同步锁用于连接等。它有一些你可以偶然访问的方法。
但是,如果您的子类Thread必须考虑实现更多Thread。
public class ThreadMain {
public int getId() {
return 12345678;
}
public String getName() {
return "Hello World";
}
public String getState() {
return "testing";
}
public void example() {
new Thread() {
@Override
public void run() {
System.out.println("id: "+getId()+", name: "+getName()+", state: "+getState());
}
}.start();
}
public static void main(String[] args) {
new ThreadMain().example();
}
}
如果你运行这个,你可能会期望
id: 12345678, name: Hello World, state: testing
然而,您并没有调用您认为是的方法,因为您使用的是Thread而不是ThreadMain中的方法,相反,您会看到类似
id: 11, name: Thread-0, state: RUNNABLE