当我启动我的应用程序时,我启动一个AsyncTask来下载。这可能需要一段时间。
当那个线程正在下载数据时,我已经在监听位置更新了。当我收到一个新的位置时,我会启动一个新的AsyncTask来进行一些处理。但是,该类依赖于下载的数据,因此必须等到下载完成:

public void setLocation(Location location) throws IOException {
    Logger.log("New location - calculating nearest stations");
    if (!initialStationsRead) {
        Logger.log("Location update waiting for stations to be read");
        while (!initialStationsRead)
            ;
        Logger.log("Location update done waiting");
    }
    /* Do the processing */
}

第一个线程在完成时将initialStationsRead设置为true,因此第二个线程可以在完成后拾取。在我的测试设备上一切正常。
不过,我收到一个用户的电子邮件,告诉我这个应用程序不会启动。加载屏幕出现,10-12秒后消失,没有任何警告。他用的是宏达电的。
这是他寄给我的那只猫:
07-05 22:11:04.938: W/dalvikvm(19961): threadid=2: spin on suspend #2 threadid=11 (pcf=1)
07-05 22:11:04.938: I/dalvikvm(19961): "GC" daemon prio=5 tid=2 RUNNABLE
07-05 22:11:04.938: I/dalvikvm(19961):   | group="system" sCount=0 dsCount=0 obj=0x40d5c580 self=0x1669ae8
07-05 22:11:04.938: I/dalvikvm(19961):   | sysTid=19965 nice=0 sched=0/0 cgrp=default handle=21931384
07-05 22:11:04.938: I/dalvikvm(19961):   | schedstat=( 0 0 0 ) utm=2 stm=0 core=1
07-05 22:11:04.938: I/dalvikvm(19961):   at dalvik.system.NativeStart.run(Native Method)
07-05 22:11:04.938: I/dalvikvm(19961): "AsyncTask #3" prio=5 tid=11 RUNNABLE JIT
07-05 22:11:04.938: I/dalvikvm(19961):   | group="main" sCount=1 dsCount=0 obj=0x40f90588 self=0x1b35b00
07-05 22:11:04.938: I/dalvikvm(19961):   | sysTid=19991 nice=0 sched=0/0 cgrp=default handle=29193008
07-05 22:11:04.938: I/dalvikvm(19961):   | schedstat=( 0 0 0 ) utm=287 stm=1 core=1
07-05 22:11:04.938: I/dalvikvm(19961):   at com.busybits.treinverkeer.data.Data.setLocation(Data.java:~102)
07-05 22:11:04.938: I/dalvikvm(19961):   at com.busybits.treinverkeer.TreinVerkeer$SetLocationAsyncTask.doInBackground(TreinVerkeer.java:408)
07-05 22:11:04.938: I/dalvikvm(19961):   at com.busybits.treinverkeer.TreinVerkeer$SetLocationAsyncTask.doInBackground(TreinVerkeer.java:1)
07-05 22:11:04.938: I/dalvikvm(19961):   at android.os.AsyncTask$2.call(AsyncTask.java:264)
07-05 22:11:04.938: I/dalvikvm(19961):   at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
07-05 22:11:04.938: I/dalvikvm(19961):   at java.util.concurrent.FutureTask.run(FutureTask.java:137)
07-05 22:11:04.938: I/dalvikvm(19961):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
07-05 22:11:04.938: I/dalvikvm(19961):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
07-05 22:11:04.938: I/dalvikvm(19961):   at java.lang.Thread.run(Thread.java:864)
07-05 22:11:05.629: D/WifiStateMachine(436): fetchRssiAndLinkSpeedNative RSSI = -32
07-05 22:11:05.689: W/dalvikvm(19961): threadid=2: spin on suspend #3 threadid=11 (pcf=1)
07-05 22:11:05.689: I/dalvikvm(19961): "GC" daemon prio=5 tid=2 RUNNABLE
07-05 22:11:05.689: I/dalvikvm(19961):   | group="system" sCount=0 dsCount=0 obj=0x40d5c580 self=0x1669ae8
07-05 22:11:05.689: I/dalvikvm(19961):   | sysTid=19965 nice=0 sched=0/0 cgrp=default handle=21931384
07-05 22:11:05.689: I/dalvikvm(19961):   | schedstat=( 0 0 0 ) utm=2 stm=0 core=1
07-05 22:11:05.689: I/dalvikvm(19961):   at dalvik.system.NativeStart.run(Native Method)
07-05 22:11:05.689: I/dalvikvm(19961): "AsyncTask #3" prio=5 tid=11 RUNNABLE JIT
07-05 22:11:05.689: I/dalvikvm(19961):   | group="main" sCount=1 dsCount=0 obj=0x40f90588 self=0x1b35b00
07-05 22:11:05.689: I/dalvikvm(19961):   | sysTid=19991 nice=0 sched=0/0 cgrp=default handle=29193008
07-05 22:11:05.689: I/dalvikvm(19961):   | schedstat=( 0 0 0 ) utm=362 stm=1 core=1
07-05 22:11:05.689: I/dalvikvm(19961):   at com.busybits.treinverkeer.data.Data.setLocation(Data.java:~102)
07-05 22:11:05.689: I/dalvikvm(19961):   at com.busybits.treinverkeer.TreinVerkeer$SetLocationAsyncTask.doInBackground(TreinVerkeer.java:408)
07-05 22:11:05.689: I/dalvikvm(19961):   at com.busybits.treinverkeer.TreinVerkeer$SetLocationAsyncTask.doInBackground(TreinVerkeer.java:1)
07-05 22:11:05.689: I/dalvikvm(19961):   at android.os.AsyncTask$2.call(AsyncTask.java:264)
07-05 22:11:05.689: I/dalvikvm(19961):   at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
07-05 22:11:05.689: I/dalvikvm(19961):   at java.util.concurrent.FutureTask.run(FutureTask.java:137)
07-05 22:11:05.689: I/dalvikvm(19961):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
07-05 22:11:05.689: I/dalvikvm(19961):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
07-05 22:11:05.689: I/dalvikvm(19961):   at java.lang.Thread.run(Thread.java:864)
07-05 22:11:05.719: D/skia(1004): AndroidImageRef[ 0x2438190 ] releasePixel fail as lockCount=1
07-05 22:11:06.439: W/dalvikvm(19961): threadid=2: spin on suspend #4 threadid=11 (pcf=1)
07-05 22:11:06.439: I/dalvikvm(19961): "GC" daemon prio=5 tid=2 RUNNABLE
07-05 22:11:06.439: I/dalvikvm(19961):   | group="system" sCount=0 dsCount=0 obj=0x40d5c580 self=0x1669ae8
07-05 22:11:06.439: I/dalvikvm(19961):   | sysTid=19965 nice=0 sched=0/0 cgrp=default handle=21931384
07-05 22:11:06.439: I/dalvikvm(19961):   | schedstat=( 0 0 0 ) utm=2 stm=0 core=1
07-05 22:11:06.439: I/dalvikvm(19961):   at dalvik.system.NativeStart.run(Native Method)
07-05 22:11:06.439: I/dalvikvm(19961): "AsyncTask #3" prio=5 tid=11 RUNNABLE JIT
07-05 22:11:06.439: I/dalvikvm(19961):   | group="main" sCount=1 dsCount=0 obj=0x40f90588 self=0x1b35b00
07-05 22:11:06.439: I/dalvikvm(19961):   | sysTid=19991 nice=0 sched=0/0 cgrp=default handle=29193008
07-05 22:11:06.439: I/dalvikvm(19961):   | schedstat=( 0 0 0 ) utm=437 stm=1 core=1
07-05 22:11:06.439: I/dalvikvm(19961):   at com.busybits.treinverkeer.data.Data.setLocation(Data.java:~102)
07-05 22:11:06.439: I/dalvikvm(19961):   at com.busybits.treinverkeer.TreinVerkeer$SetLocationAsyncTask.doInBackground(TreinVerkeer.java:408)
07-05 22:11:06.439: I/dalvikvm(19961):   at com.busybits.treinverkeer.TreinVerkeer$SetLocationAsyncTask.doInBackground(TreinVerkeer.java:1)
07-05 22:11:06.439: I/dalvikvm(19961):   at android.os.AsyncTask$2.call(AsyncTask.java:264)
07-05 22:11:06.439: I/dalvikvm(19961):   at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
07-05 22:11:06.439: I/dalvikvm(19961):   at java.util.concurrent.FutureTask.run(FutureTask.java:137)
07-05 22:11:06.439: I/dalvikvm(19961):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
07-05 22:11:06.439: I/dalvikvm(19961):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
07-05 22:11:06.439: I/dalvikvm(19961):   at java.lang.Thread.run(Thread.java:864)

重复X次。
现在,Data.java:102是行,所以肯定出了问题。
发生了什么,我该怎么解决?

最佳答案

第一个线程在完成时将initialstationsread设置为true,这样第二个线程就可以在完成后进行拾取。
繁忙的循环是邪恶的化身。如果我手边有圣水的话,你现在会很湿的。-)
(这也意味着我有很好的圣水远射目标,但事实并非如此)
Java有很多线程同步的选项,并且已经有十年了,从低级wait()notify() on Objectjava.util.concurrent构造,如Semaphore。选一个,用它,摆脱繁忙的循环。
或者,按照jan henk的建议,基于一个标志,在同一个线程上连续地执行该工作。
你知道为什么这会发生在他的设备上,而不是我的或其他我认识的人的设备上吗?
好吧,首先,一个s是双核的,所以你的线程可能同时运行(每个核一个)。在多核环境中,线程问题更容易出现。
另外,安吉洛的回答——我写这篇文章的时候贴出来的——也值得注意。

10-08 08:06
查看更多