所以我需要使用 [this != currentThread()] 检查我是否不在“main”的同一个线程中。 行为:扩展线程和实现 Runnable 的行为会有所不同。为什么?
为什么当我扩展线程时此代码将运行:
public class Demo {
public static void main(String[] arg) {
MyThread a = new MyThread();
a.start();
a.run();
}
private static class MyThread extends Thread {
@Override
public void run() {
if (this != currentThread()) {
throw new IllegalStateException("run() must not be called directly");
}
System.out.println(getName() + " run started...");
for (int i = 1; i < 100; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
System.out.println('\n' + getName() + " run ended.");
}
}
}
但是,当我实现 Runnable 时,我收到错误 - 代码:
import static java.lang.Thread.currentThread;
public class Demo {
public static void main(String[] arg) {
Thread t1 = new Thread(new MyThreadRunnable());
t1.start();
// t1.run();
}
private static class MyThreadRunnable implements Runnable {
@Override
public void run() {
if (this != currentThread()) { // I get an error here
throw new IllegalStateException("run() must not be called directly");
}
Thread thread = currentThread();
System.out.println(thread.getName() + " run started...");
for (int i = 1; i < 100; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
System.out.println('\n' + thread.getName() + " run ended.");
}
}
}
我缺少什么?
在第二个示例中
MyThreadRunnable
不扩展 Thread
。 Thread.currentThread()
仅返回 Thread
实例(即 java.lang.Thread
的实例或 java.lang.Thread
子类的实例)。
Java 语言规范描述了这种情况 15.21.3。参考相等运算符 == 和 !=:
如果无法通过强制转换将任一操作数的类型转换为另一个操作数的类型(第 5.5 节),则这是一个编译时错误。两个操作数的运行时值必然不相等(忽略两个值都为空的情况)。
由于您无法将
MyThreadRunnable
投射到 Thread
或将 Thread
投射到 MyThreadRunnable
(两者都会抛出 ClassCastException
),因此适用此规则。
您可以向
Runnable
添加强制转换以使其编译:
if ((Runnable) this != currentThread()) {
throw new IllegalStateException("run() must not be called directly");
}
但这总是会抛出
IllegalStateException
,因为 this
永远不可能是 Thread
实例。