外围Java线程方法背景工作对调用线程的影响

时间:2013-03-29 15:48:37

标签: java android multithreading

我有一个基于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?

2 个答案:

答案 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,或者定时等待。

相关问题