当我启动我的应用程序时,我启动一个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 Object
到java.util.concurrent
构造,如Semaphore
。选一个,用它,摆脱繁忙的循环。
或者,按照jan henk的建议,基于一个标志,在同一个线程上连续地执行该工作。
你知道为什么这会发生在他的设备上,而不是我的或其他我认识的人的设备上吗?
好吧,首先,一个s是双核的,所以你的线程可能同时运行(每个核一个)。在多核环境中,线程问题更容易出现。
另外,安吉洛的回答——我写这篇文章的时候贴出来的——也值得注意。