我偶然发现了一个非常奇怪的问题,我对此毫无意义。首先介绍一些背景知识:
我正在尝试运行JavaScriptCore并将其用作Android应用程序的各种脚本语言。问题在于,较旧的Android版本(例如API 16上的12k)在主线程上的堆栈大小非常有限。但是,我仍然想在主线程上调用JS,让它回调以请求事物,并使所有这些事物看起来都是同步的。没问题-我会介绍一些方法... khm ... SynchronousQueues并来回反弹执行。 Here's what my code looks like.
这非常简单-每次调用defer时-都会反弹到另一个线程并从那里继续。唯一的问题是,它不起作用。在执行Javascript代码的实际用例中,尽管在仿真器和不同设备上不在同一地点,但它确实在某个时候确实可靠地失败了。 Logcat总是看起来很无害:
I/JavaScriptCore: Lockstep [Main]: Defer
I/JavaScriptCore: Lockstep [Main]: Send EXECUTE_FUNC
I/JavaScriptCore: Lockstep [Background]: Receive EXECUTE_FUNC
I/JavaScriptCore: Lockstep [Background]: Defer
I/JavaScriptCore: Lockstep [Background]: Send EXECUTE_FUNC
但是,即使看跌期权通过了,第二个EXECUTE也永远不会被main接收。据我了解,同步队列甚至不可能做到这一点。查看线程转储,后台线程在运行循环中等待下一条消息,而main则停在incoming.take上。没有其他线程与此交互。
在我的其中一台设备上,我可以为条件断点设置一个确切的断点,以使其不再起作用,并且可以在MAIN正在等待该EXECUTE消息时暂停它。该消息非空,此时的前台队列正在运行,无论是否有超时,我都可以通过Android Studio对其进行轮询,无论其大小如何。一旦我完成所有操作,挂起。
当然,我怀疑是JNI的恶作剧,但在Logcat中根本没有内存转储,段错误或任何警告。
另外,这不只是花时间-即使我是在非常肮脏的繁忙等待中这样做的:
Message msg = incoming.poll();
if(msg == null) {
Thread.sleep(20);
continue;
}
Main卡在民意测验上,后台线程每20毫秒就在另一个队列上忙碌地跑来跑去。
我试着用一个非常喜欢睡觉的非常懒惰的阶乘嵌套延迟,尽管有200个深度,但整数溢出没有问题:
LockstepThread t = new LockstepThread();
int deferredFactoriel(final int n) {
if(n == 0) {
return 1;
}
return n * t.defer(new Functor<Integer>() {
@Override
public Integer call() {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
return deferredFactoriel(n-1);
}
});
}
@Override
public void onCreate() {
super.onCreate();
for(int i=0; i<200; ++i) {
Log.i("Test", i+"! = " + deferredFactoriel(i));
}
...
可能最奇怪的是,我使用什么同步都没有关系。 SynchronizedQueue,ArrayBlockingQueue,LinkedBlocking队列-它始终在具有完全相同的线程转储的同一位置失败。 hell ,我什至制作了自己的exchanger只是为了看看我并没有发疯,而且它仍然以同样的方式卡住了。
是的,我完全陷入了困境。有什么想法吗?调试方面的任何帮助将不胜感激。
最佳答案
static Timer timer;
private TimerTask timerTask;
try {
timer = new Timer();
timerTask = new TimerTask() {
@Override
public void run() {
}
}
};
timer.schedule(timerTask, 4000);
} else {
timer.cancel();
// timer.purge();
MainHomeActivity.appendLogSocket("UPDATE RECEIVER : ",
"TIMER STOPED");
}
} catch (Exception e) {
Log.e( "Socket update receiever error: ", e.toString());
}