Java 线程在BlockingQueue.take上被卡住,原因不明
我偶然发现了一个非常奇怪的问题,我什么都搞不懂。先讲一点背景故事: 我正在尝试运行JavaScriptCore,并将其用作Android应用程序的某种脚本语言。问题是,在较旧的Android版本上,主线程上的堆栈大小非常有限(在API 16上类似于12k)。然而,我仍然希望在主线程上调用JS,让它回调请求,并让所有这些都显示为同步的。没问题-我会想出几个办法。。。高棉。。。SynchronousQueues并来回反弹执行 这很简单,每次有东西调用defer时,它都会跳转到另一个线程并从那里继续。唯一的问题是,它不起作用。在执行Javascript代码的实际用例中,它在某个点上会非常可靠地失败,尽管对于模拟器和不同的设备来说不是在同一点上。Logcat看起来总是非常无害:Java 线程在BlockingQueue.take上被卡住,原因不明,java,android,concurrency,android-ndk,Java,Android,Concurrency,Android Ndk,我偶然发现了一个非常奇怪的问题,我什么都搞不懂。先讲一点背景故事: 我正在尝试运行JavaScriptCore,并将其用作Android应用程序的某种脚本语言。问题是,在较旧的Android版本上,主线程上的堆栈大小非常有限(在API 16上类似于12k)。然而,我仍然希望在主线程上调用JS,让它回调请求,并让所有这些都显示为同步的。没问题-我会想出几个办法。。。高棉。。。SynchronousQueues并来回反弹执行 这很简单,每次有东西调用defer时,它都会跳转到另一个线程并从那里继续。
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
然而,第二次执行从未被main接收,即使put通过。据我所知,同步队列甚至不可能做到这一点。查看线程转储,后台线程正在运行循环中等待下一条消息,而main则停在incoming.take上。没有其他线程与此进行交互
在我的一台设备上,我可以设置一个条件断点,在它停止工作的确切时刻,我可以暂停它,就像MAIN正在等待执行消息一样。消息是非空的,此时的foregroundQueue正在工作,我可以从Android Studio轮询它,不管有没有超时,不管大小。我一跨过所有的工序就挂了
当然,我怀疑JNI的诡计,但在Logcat中没有内存转储、分段错误或任何警告
而且,这不仅仅是一种享受——即使我在等待的过程中非常忙碌:
Message msg = incoming.poll();
if(msg == null) {
Thread.sleep(20);
continue;
}
Main被阻塞在poll上,后台线程每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));
}
...
LockstepThread t=新的LockstepThread();
整数延迟因子(最终整数n){
如果(n==0){
返回1;
}
返回n*t.defer(新函子(){
@凌驾
公共整数调用(){
试一试{
睡眠(20);
}捕捉(中断异常e){
e、 printStackTrace();
}
返回延迟因子(n-1);
}
});
}
@凌驾
public void onCreate(){
super.onCreate();
对于(int i=0;i
为什么要使用线程。线程也有替换。请尝试
这样使用:可能是它的作品
请展示一个示例Functor,我怀疑您的Functor对defer/runLoop的嵌套调用错误,导致死锁。正如@glee8e所说:Functor
中的代码似乎有问题。您的示例代码没有显示如何从后台线程调用defer
,但您的日志跟踪显示了这种情况。
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());
}