gpt4 book ai didi

java - 外围 Java 线程方法的后台工作对调用线程的影响

转载 作者:行者123 更新时间:2023-12-02 07:09:29 33 4
gpt4 key购买 nike

我有一个基于 Java 的应用程序 (Android),我希望能够在后台执行可能长时间的操作。 AsyncTask 上的 Android 文档建议不要将它们用于可能运行时间超过几秒的任务(这是为什么?),因此我使用 Java Thread 的子类来代替。该 Thread 子类 (HPCHeadThread) 的目标主要是托管一些异步控制机制的实例,并为所述机制提供访问器方法以供其他线程使用。我的目标工作流程是能够从任何引用 HPCHeadThread 的线程调用 hHPCHeadThread.doStuff(),并让在 HPCHeadThread 中实例化的控制对象在 HPCHeadThread 线程上且仅在该线程上工作。当没有被其他线程访问时,HPCHeadThread 应该 hibernate ,以免浪费 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() 方法 while 循环中引发 InterruptedException?

最佳答案

Android 文档建议不要在 Activity 中长时间运行线程,因为 Activity 可以在系统需要内存且应用程序在后台运行时随时被换出。

如果您想要执行长时间运行的任务:创建一个专门用于以下目的的服务:在需要更多内存时不应丢弃长时间运行的任务。

关于队列的事情:听起来是个好建议。只需使用具有阻塞调用的 ArrayBlockingQueue:take()

像这样创建工作线程和队列:

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);

这可以从任何线程调用而不会阻塞它,它将任务添加到队列中,该队列将被一一执行。

关于java - 外围 Java 线程方法的后台工作对调用线程的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15706613/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com