我有一个Runnable(比如“ MyThread ”),它执行一个长任务,并且还使用/锁定一个线程安全的单例。
我注意到当按下后退按钮时,屏幕会立即退出活动,并且没有视觉指示 MyThread 已正确完成。
事实证明,当我打开'我的应用程序时,单身人士仍然被锁定!当然 getLockedInstance()返回null。
所以我想我的问题是...... 当按下后退按钮时,甚至在执行关键任务时,Android应用程序究竟发生了什么?线程终止了吗?活动的线程是否被冻结,因此所有数据都被访问和使用?我们如何确保允许关键任务完成执行?
// singleton class
public class Storage
{
private int count = 0;
private static final Storage ourInstance = new Storage();
public static synchronized Storage getLockedInstance()
{
if (ourInstance.count > 0)
return null;
ourInstance.count++;
return ourInstance;
}
public synchronized void UnlockInstance()
{
if (count > 0)
count--;
}
}
// runnable declaration
private Runnable MyThread = new Runnable()
{
@Override
public void run()
{
Storage s = Storage.getLockedInstance();
..... do stuff .....
[back button pressed]
..... this is never reached .....
s.UnlockInstance();
}
}
答案 0 :(得分:1)
Android中的Thread类与常规Java编程中的Thread类没有什么不同。它是应用程序获得的底层Linux本机线程的最接近的表示形式。 Thread类为任务创建执行环境,由Runnable表示。 Thread实现Runnable,因此要执行的任务由线程本身定义或在线程创建期间注入。
当run方法执行完毕后,线程终止并且可以释放其资源。这是线程的最终状态;不能重用Thread实例或其执行环境。
中断(例如按后退按钮)
有时,应用程序希望在完成任务之前终止线程的执行。例如,如果线程花费很长时间来下载视频并且用户按下按钮以取消下载,则UI线程捕获按钮按下并且想要终止下载线程。但是,线程无法直接终止。相反,线程可以被中断,这是对应该终止的线程的请求,但是线程本身决定是否强制。在线程引用上调用中断:
线程中断是协同实现的:线程使其自身可以被中断,而其他线程发出调用来中断它。发出中断对线程的执行没有直接影响;它只是在线程上设置一个标记为中断的内部标志。被中断的线程必须检查标志本身以检测中断并正常终止。线程必须实现取消点,以允许其他线程中断它并使其终止。
答案 1 :(得分:0)
(代表OP发布)。
感谢大家(和A. A.J A.J)的意见和帮助。我误解了这个问题,实际上问题是我的。
线程确实完成了执行,但由于它是一个很长的进程,因此对应用程序恢复的任何活动都会阻止对Storage对象的访问。我的解决方案是使用getLockedInstanceWait()函数(见下文)而不是"锁定并返回"先前使用的类型:
public static Storage getLockedInstanceWait()
{
Storage s = null;
while ((s = Storage.getLockedInstance()) == null)
{
try
{
Thread.sleep(500);
}
catch (InterruptedException e)
{
return null;
}
}
return s;
}