DispatchQueue介绍
在特定的线程(单线程)下串行执行的任务队列
DispatchQueue作用
在特定的线程中串行执行耗时的或者涉及网络操作的任务
比如数据库操作,Android的sqlite数据库不支持并发操作,又不好在主线程中执行,所以在线程中串行执行对数据库的操作是安全的且不会阻塞主线程的。
DispatchQueue代码
public class DispatchQueue extends Thread {
private volatile Handler handler = null;
//作用:创建指定线程下的Handler并创建指定的消息队列好和消息循环之前保证添加的任务等待到创建成功后再添加。
private CountDownLatch syncLatch = new CountDownLatch(1);
/**
*
* @param threadName 任务队列所在的线程名
*/
public DispatchQueue(final String threadName) {
setName(threadName);
start();
}
private void sendMessage(Message msg, int delay) {
try {
syncLatch.await();
if (delay <= 0) {
handler.sendMessage(msg);
} else {
handler.sendMessageDelayed(msg, delay);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
/**
* 取消任务
* @param runnable
*/
public void cancelRunnable(Runnable runnable) {
try {
syncLatch.await();
handler.removeCallbacks(runnable);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
/**
* 立刻添加顺序执行的任务
* @param runnable
*/
public void postRunnable(Runnable runnable) {
postRunnable(runnable, 0);
}
/**
* 延时添加顺序执行的任务
* @param runnable
*/
public void postRunnable(Runnable runnable, long delay) {
try {
syncLatch.await();
if (delay <= 0) {
handler.post(runnable);
} else {
handler.postDelayed(runnable, delay);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
/**
* 清空任务队列
*/
public void cleanupQueue() {
try {
syncLatch.await();
handler.removeCallbacksAndMessages(null);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
@Override
public void run() {
Looper.prepare();
handler = new Handler();
syncLatch.countDown();
Looper.loop();//做的操作是个死循环,线程才不会结束。
}
}
DispatchQueue代码分析
Android中的Handler是用于分发消息和任务的组件,并且是工作在单个线程中,所以任务执行时串行执行的。
在线程中创建的Handler是不会自动创建消息队列和进行消息循环操作的,所以需要手动创建消息队列和进行消息循环。
由于创建Handler是在线程中进行的,所以需要对添加任务到队列和创建Handler的任务进行同步,确保添加任务的线程在创建Handler线程之后,所以使用CountDownLatch (计数减少锁)对线程进行同步。
DispatchQueue使用演示
public class TestActivity extends Activity {
public static class DemoTask implements Runnable{
int index;
public DemoTask(int index){
this.index = index;
}
@Override
public void run() {
String tag = Thread.currentThread().getName();
Log.e(tag," 第 "+index+"任务开始");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e(tag," 第 "+index+"任务完成");
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DispatchQueue dispatchQueue = new DispatchQueue("任务队列线程");
for (int i = 0; i < 10; i++) {
DemoTask demoTask = new DemoTask(i);
dispatchQueue.postRunnable(demoTask);
}
}
}