我有一个基于Java的应用程序(Android),我希望能够在后台执行潜在的长时间操作。 AsyncTask上的Android文档建议不要将它们用于可能运行超过几秒钟的任务(为什么会这样?)所以我正在使用Java的Thread的子类。此Thread子类(HPCHeadThread)的目标主要是托管一些异步控制机制的实例,并为所述其他线程使用的机制提供访问器方法。我的目标工作流程是能够从任何引用HPCHeadThread的线程调用hHPCHeadThread.doStuff(),并且在HPCHeadThread中实例化的控件对象可以在HPCHeadThread线程上工作,并且仅在该线程上工作。当不被另一个线程访问时,HPCHeadThread应该休眠,以免浪费CPU周期。我从主线程(TestActivity)启动外围线程HPCHeadThread,如下所示:
TestActivity.java
//..snip
private HPCHeadThread hHPCHeadThread;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//...snip
//Create and start our HPCHeadThread
hHPCHeadThread = HPCHeadThread.getHPCThreadHead();
hHPCHeadThread.start();
//..snip
}
HPCHeadThread.java
//..snip
public class HPCHeadThread extends Thread {
private static volatile HPCHeadThread instance;
private static boolean bIsActive = true;
private HPCHeadThread(){
super();
}
public static HPCHeadThread getHPCThreadHead(){
if(instance == null && bIsActive){
instance = new HPCHeadThread();
}
return instance;
}
public void safeStop(){
instance = null;
bIsActive = false;
}
@Override
public void run(){
Thread thisThread = Thread.currentThread();
Thread.currentThread().setName("HPC_Head_Thread");
while(instance == thisThread){
//Our HPCHeadThread 'main' loop
//Try to have it sleep whenever it isn't being used
//Hopefully it will wake nicely upon attempted access,
//perform the desired function, and then return to sleep
try{
Thread.sleep(10000);
}
catch (InterruptedException e){
//e.printStackTrace();
}
}//End while
}//End Run()
public void doStuff(){
//..snip stuff..
}
}
现在,如果我从主TestActivity线程中调用hHPCHeadThread.doStuff(),那么HPCHeadThread或主TestActivity线程上的工作进程是否正常? TestActivity在继续在其自己的线程中执行顺序执行之前是否等待doStuff()方法返回?方法调用是否唤醒HPCHeadThread和/或它们是否导致在循环中在HPCHeadThread的run()方法中抛出InterruptedException?
答案 0 :(得分:2)
Android文档针对活动中长时间运行的线程提供建议,因为在系统需要内存且应用程序在后台运行时,可以交换活动。
如果您想要执行长时间运行的任务:创建一个仅用于此目的的服务:长时间运行的任务,当需要更多内存时,不应该抛出这些任务。
在排队的事情上:听起来像个好建议。只需使用具有阻塞调用的ArrayBlockingQueue:take()
像这样创建你的workerthread和队列:
public class Workqueue implements Runnable {
private static Workqueue theInstance=null;
public static synchronized Workqueue getInstance(){
if(theInstance==null){
theInstance=new WorkQueue();
}
return theInstance;
}
private ArrayBlockingQueue<Runnable> queue=new ArrayBlockingQueue<Runnable>();
private Thread workerThread;
private WorkQueue(){
workerThread=new Thread(this);
workerThread.start();
}
public void run(){
while(keepRunning){
//pick up next task or wait (not using any cpu cycles)
Runnable r=queue.take();
//execute task
r.run();
}
}
public void addTask(Runnable task){
queue.add(task);
}
用法是:
Runnable newTask= new Runnable(){
public void run(){
dostuff...
}};
Workqueue.getInstance().addTask(newTask);
可以从任何线程调用它而不阻塞它,它会将任务添加到队列中,逐个执行。
答案 1 :(得分:0)
首先,我认为你可以使用旧的Singleton设计模式来完成从任何地方访问一个线程。它看起来像是:
public class MyThread extends Thread () {
private static MyThread _me;
private MyThread() { /* make constructors private it can only be made by getting an instance */ }
public static MyThread getInstance() {
if(_me == null) {
_me = new MyThread();
}
return _me;
}
}
其次,调用doStuff()将在调用线程中运行。在Java Thread中,所有Thread的处理都在run()方法中进行。
最后,如果线程不需要立即执行,您可能需要查看实现wait和notify,或者定时等待。