我偶然发现了一个非常奇怪的问题,我对此毫无意义。首先介绍一些背景知识:

我正在尝试运行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());

            }

08-05 21:04