在Android应用程序的UI线程中,我需要运行一个可能需要纳秒或永远才能完成的方法。我想我不能确切地确定什么时候需要永远,所以我在一个单独的线程中通过一个池来运行它。
myPool = Executors.newCachedThreadPool(new ThreadFactory(){
//override newThread(Runnable r)...
});
Future<Result> futureResult = myPool.submit(new Callable<Result>(){
@Override public Result call(){
return dangerousMethod();
}
});
try{
Result result = futureResult.get(1, TimeUnit.SECONDS);
//Use result here
}catch(TimeoutException e) {//Other Exceptions are ommited
futureResult.cancel(true);
Log.d("DEMO", "Method takes too long. Skip");
}
futureResult.cancel(true)
,但
dangerousMethod()
不会对中断做出响应,因此线程将继续运行,直到最终完成其任务。
ThreadPoolExecutor
并获得私人
Thread
ThreadPoolExecutor$Worker.thread
)强制(不良行为TM)执行以下任一操作:
stop()
(不工作,因为
UnsupportedOperationException
)或者
stop0()
(也不工作,因为
NoSuchMethodException
). 更多详细信息:
class MyPool extends ThreadPoolExecutor{
//constructor, reflection code to get the Threads, etc
void cancelThread(Thread thread){
try {
thread.stop();
}catch(SecurityException | UnsupportedOperationException e) {
try {
Method stopMethod = Thread.class.getDeclaredMethod("stop0", Object.class);
stopMethod.setAccessible(true);
stopMethod.invoke(thread, new ThreadDeath());
}catch(NoSuchMethodException |
InvocationTargetException |
IllegalAccessException x)
{
Log.d("MyPool", "Can't stop thread", x);
}
}
}
}
危险的方法实际上是这样的:
BigDecimal n1 = new BigDecimal("1E1000000");
BigDecimal n2 = new BigDecimal("1");
BigDecimal result = n1.add(n2);//Takes too long
BigDecimal n3 = new BigDecimal("1E999999");
BigDecimal result = n1.add(n3);