Process中定义,值越小,优先级越高,默认是THREAD_PRIORITY_DEFAULT 0
最简单,常用的线程使用方式 - 不能够重复使用,频繁创建会造成很大的开销 - 在复杂的场景也不容易使用
自带消息循环的线程 - 串行执行 - 长时间运行,不断从队列中获取任务
HandlerThread
是 Android 封装的一个线程类,将 Thread 跟 Handler 封装。使用步骤如下:
HandlerThread mHandlerThread = new HandlerThread("mHandlerThread");
mHandlerThread .start();
创建Handler
对象,重写handleMessage
方法
<br /> Handler mHandler= new Handler( mHandlerThread.getLooper() ) {
@Override
public boolean handleMessage(Message msg) {
//消息处理
return true;
}
});
<br /> Message message = Message.obtain();
message.what = “2”
message.obj = "骚风"
mHandler.sendMessage(message);
mHandlerThread.quit();
是一个Android线程封装类,将Thread与handler
结合使用
优势:
劣势:
IntentService
是 Service 的子类,默认为我们开启了一个工作线程,使用这个工作线程逐一处理所有启动请求,在任务执行完毕后会自动停止服务,使用简单,只要实现一个方法 onHandleIntent
,该方法会接收每个启动请求的 Intent,能够执行后台工作和耗时操作。可以启动 IntentService
多次,而每一个耗时操作会以队列的方式在 IntentService 的 onHandlerIntent
回调方法中执行,并且,每一次只会执行一个工作线程,执行完第一个再执行第二个。并且等待所有消息都执行完后才终止服务。
IntentService
适用于 APP 在不影响当前用户的操作的前提下,在后台默默的做一些操作。
IntentService
源码:
HandlerThread
单独开启一个名为 IntentService
的线程
ServiceHandler
的内部 Handler
Handler与HandlerThread
所对应的子线程进行绑定
onStartCommand()
传递给服务 intent,依次插入到工作队列中,并逐个发送给 onHandleIntent()
onHandleIntent()
来依次处理所有 Intent 请求对象所对应的任务
使用示例:
<br />public class MyIntentService extends IntentService {
public static final String TAG ="MyIntentService";
public MyIntentService() {
super("MyIntentService");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
boolean isMainThread = Thread.currentThread() == Looper.getMainLooper().getThread();
Log.i(TAG,"is main thread:"+isMainThread); // 这里会打印false,说明不是主线程
// 模拟耗时操作
download();
}
/**
* 模拟执行下载
*/
private void download(){
try {
Thread.sleep(5000);
Log.i(TAG,"下载完成...");
}catch (Exception e){
e.printStackTrace();
}
}
}
Android 提供工具类,无需自己处理线程切换 使用及源码详解见 https://www.ztzyif.top/index.php/2019/07/16/asynctask-%e6%ba%90%e7%a0%81%e8%a7%a3%e6%9e%90/
Java提供的线程池 - 容易复用,减少频繁创建及销毁时间 - 功能强大:定时、任务队列,并发控制
由强大的Scheduler
集合组成
源码详解见
https://www.ztzyif.top/index.php/2019/07/17/rxjava2-%e8%a7%a3%e6%9e%90/
创建线程必须命名
- 方便进行定位线程归属
- 运行期间调用Thread.currentThread.setName()
修改名字
重视优先级设置
Process.setThreadPriority()
public class ThreadPoolUtils {
private int CPUCOUNT = Runtime.getRuntime().availableProcessors();
private ThreadPoolExecutor cpuExecutor = new ThreadPoolExecutor(CPUCOUNT, CPUCOUNT,
30, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>(), sThreadFactory);
private ThreadPoolExecutor iOExecutor = new ThreadPoolExecutor(64, 64,
30, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>(), sThreadFactory);
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
//对每个线程进行命名,原子性的自增
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "ThreadPoolUtils #" + mCount.getAndIncrement());
}
};
public static ExecutorService getService() {
return sService;
}
private static ExecutorService sService = Executors.newFixedThreadPool(5, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, "ThreadPoolUtils");
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
return thread;
}
});
}
// 以下代码是为了演示修改任务的名称
ThreadPoolUtils.getService().execute(new Runnable() {
@Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
String oldName = Thread.currentThread().getName();
Thread.currentThread().setName("new Name");
LogUtils.i("");
Thread.currentThread().setName(oldName);
}
});