我有这样的代码
boolean start = false;
ThreadX a = new ThreadX();
a.start();
start = true;
Class ThreadX extends Thread {
public void run() {
while (start == true) {
...
}
}
}
这段代码有问题吗?我已经执行了这个并且没有看到任何问题只是想要挂起是否线程将启动并且从不执行start = true
答案 0 :(得分:6)
有两个问题:
start
设置为true之前启动,因此立即终止。start
设置为true后启动,但是从不设置start
更改的值(假设它在原始线程中的某处设置为false)由于缺乏记忆障碍要么变量volatile,要么使用锁,要么使用java.util.concurrent.atomic中的AtomicXXX
类型之一,例如: AtomicBoolean
。另外,对于良好实践,您应该实现Runnable
而不是扩展Thread
- 您不希望更改线程的基本行为,您只想为其提供任务。 (您可以扩展线程来执行此操作的事实是IMO的设计缺陷。)
答案 1 :(得分:3)
是的,有问题。
假设start
是一个局部变量,这个代码甚至不会编译,因为内部类中使用的所有局部变量都必须是final
。
假设start
是某个类的字段。然后必须将该字段声明为volatile
,否则无法保证如果一个线程更改了该变量,则其他线程将看到该更改。
答案 2 :(得分:1)
这取决于start
在run()
开始之前或之后是否成立。我说“这取决于”,因为JVM无法保证会出现这种情况。当然,这是假设start
在您的线程实例的范围内。
答案 3 :(得分:0)
这样就无法确保循环进入:
如果线程被启动并且当前线程(启动另一个线程的线程)被中断,那么另一个线程可以运行while条件将为false并且运行将退出
另一方面,如果当前线程没有被中断并且设置start为true,则循环将进入
这被称为竞争条件
答案 4 :(得分:0)
线程将启动,但可能会立即退出,稍后退出或永远运行:
场景1 - 永远运行 在thread run()进入之前,start更新为true,jvm决定将它写入内存,这样创建的线程就会将其视为true,并且永远不会终止。
场景2 - 立即退出 在run()开始之前,start更新为true但是jvm不更新物理内存(没有membar),然后运行continue并看到false,并且将终止,或者run()和循环在第一次运行之前运行=是运行。
场景3 - 在某个时候退出 在run()之前或run()之后更新start,但jvm在运行后的某个时刻更新物理内存进行多次迭代。