Java 线程在BlockingQueue.take上被卡住,原因不明

Java 线程在BlockingQueue.take上被卡住,原因不明,java,android,concurrency,android-ndk,Java,Android,Concurrency,Android Ndk,我偶然发现了一个非常奇怪的问题,我什么都搞不懂。先讲一点背景故事: 我正在尝试运行JavaScriptCore,并将其用作Android应用程序的某种脚本语言。问题是,在较旧的Android版本上,主线程上的堆栈大小非常有限(在API 16上类似于12k)。然而,我仍然希望在主线程上调用JS,让它回调请求,并让所有这些都显示为同步的。没问题-我会想出几个办法。。。高棉。。。SynchronousQueues并来回反弹执行 这很简单,每次有东西调用defer时,它都会跳转到另一个线程并从那里继续。

我偶然发现了一个非常奇怪的问题,我什么都搞不懂。先讲一点背景故事:

我正在尝试运行JavaScriptCore,并将其用作Android应用程序的某种脚本语言。问题是,在较旧的Android版本上,主线程上的堆栈大小非常有限(在API 16上类似于12k)。然而,我仍然希望在主线程上调用JS,让它回调请求,并让所有这些都显示为同步的。没问题-我会想出几个办法。。。高棉。。。SynchronousQueues并来回反弹执行

这很简单,每次有东西调用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
然而,第二次执行从未被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());

            }