Java 简单线程崩溃Android应用程序
在Android应用程序中创建一个启动线程时,我发现了一个非常奇怪的问题 如果我有以下类线程: 并将其添加到活动的onCreate(…)方法中的某个位置,如: 应用程序将崩溃 但是如果我将run()方法更改为: 它停止撞击 即使我通过使用锁、notify()和wait()解决了问题,问题仍然存在:Java 简单线程崩溃Android应用程序,java,android,multithreading,Java,Android,Multithreading,在Android应用程序中创建一个启动线程时,我发现了一个非常奇怪的问题 如果我有以下类线程: 并将其添加到活动的onCreate(…)方法中的某个位置,如: 应用程序将崩溃 但是如果我将run()方法更改为: 它停止撞击 即使我通过使用锁、notify()和wait()解决了问题,问题仍然存在: 为什么使用直接访问字段时,应用程序会继续工作,而使用该方法时会崩溃?首先,由于您没有提供MCVE,其他人无法重现您的问题。这是不幸的,因为这意味着我们无法确定问题的真正原因是什么。我们只能提出假
为什么使用直接访问字段时,应用程序会继续工作,而使用该方法时会崩溃?首先,由于您没有提供MCVE,其他人无法重现您的问题。这是不幸的,因为这意味着我们无法确定问题的真正原因是什么。我们只能提出假设 有些人假设你的问题是由其他原因造成的;e、 g.GUI线程上的无限循环。这是有道理的,但没有明确的证据证明这一点。(我们看不到代码……) 我的假设是这是一个“记忆可见性”问题。Java语言规范有一章定义了一个线程保证看到另一个线程写入内存的值的情况。这些规则相当复杂且技术性很强,但本质上是需要分析一个线程写入的内存与另一个线程读取的后续内存之间是否存在先发生后发生的关系。有很多东西可以让你建立这种关系:
- 线程写入/读取共享的易失性变量
- 正在使用相同锁进行同步的线程
- 发条
- 螺纹接头
- 构造函数的完成(对于
最终
变量)
running
变量,您的程序中不存在这些内容。这意味着不能保证在running
变量上循环的线程将看到另一个线程发出的setRunning
调用的结果:
- 它可能会立即看到更改
- 以后可能会看到这些变化
- 它可能永远也见不到他们
running
声明为volatile
另一种解决方案是将isRunning()
和setRunning
声明为synchronized
方法
其中任何一个都足以提供“先发生后发生”的关系。。。并确保
isRunning()
看到了setRunning()
所做的更新,您是否正在使用布尔运行代码>和非布尔运行
?您可以发布stacktrace吗?您是否尝试过初始化该值,以便getRunning()
肯定会返回一些内容,而不是未初始化的变量?还有,这里要问的问题是什么,你似乎已经修复了你的崩溃?哪一个是您的错误?没有任何stacktrace?我认为问题不是您的TroubleThread,而是UI线程,它可能正在等待一些需要大量时间的事情。我已经用直接访问布尔值和通过get方法测试了您的解决方案,效果很好。因此,我认为这应该取决于您在UI线程中尝试做什么。但是,您可能只需要同步对共享变量的访问。
public class TroubleThread extends Thread{
boolean running;
public boolean isRunning() {
return running;
}
public void setRunning(boolean running) {
this.running = running;
}
@Override
public void run() {
while (isRunning()){
}//end while
}//end run
}
public class MyActivity extends Activity {
TroubleThread myThread;
@Override
public void onCreate(Bundle savedInstanceState) {
//....
myThread = new TroubleThread();
myThread.setRunning(true);
myThread.start();
}
}
@Override
public void run() {
while (running){ //NOTE THE USE OF DIRECT FIELD ACCESS INSTEAD OF METHOD
}//end while
}//end run