Android中让多个线程顺序执行探究
线程调度是指按照特定机制为多个线程分配CPU的使用权。
有两种调度模型:分时调度模型和抢占式调度模型。
分时调度模型:是指让所有的线程轮流获得cpu的使用权,并且平均分配每个线程占用的CPU的时间片。
抢占式调度模型:是指优先让可运行池中优先级高的线程占用CPU,如果可运行池中的线程优先级相同,那么就随机选择一个线程,使其占用CPU。处于运行状态的线程会一直运行,直至它不得不放弃CPU。一个线程会因为以下原因而放弃CPU:
1 、java虚拟机让当前线程暂时放弃CPU,转到就绪状态,使其它线程或者运行机会。
2、 当前线程因为某些原因而进入阻塞状态
3、 线程结束运行
需要注意的是,线程的调度不是跨平台的,它不仅仅取决于java虚拟机,还依赖于操作系统。在某些操作系统中,只要运行中的线程没有遇到阻塞,就不会放弃CPU;在某些操作系统中,即使线程没有遇到阻塞,也会运行一段时间后放弃CPU,给其它线程运行的机会,java的线程调度是不分时的,同时启动多个线程后,不能保证各个线程轮流获得均等的CPU时间片。如果希望明确地让一个线程给另外一个线程运行的机会,可以采取以下办法之一:调整各个线程的优先级、让处于运行状态的线程调用、Thread.sleep()方法、让处于运行状态的线程调用Thread.yield()方法、让处于运行状态的线程调用另一个线程的join()方法
所以,让多个线程顺序执行有三个确切的办法:
1、改变线程的优先级(不同的系统上可能并不会按照优先级来执行)
2、调用join()方法,一个线程在run中调用join()方法时,会阻塞当前线程,而让新加入的线程执行完再执行本线程
3、第三个方法是我自己想出来的,就是使用PriorityQueue优先队列,PriorityQueue有这样一个特征,就是可以让队列中某个优先级最高元素最先出来,所以利用这个特性,可以让我们想要哪个线程先执行就先执行,最后通过线程的State来判断该线程是否执行完毕,再执行下一个线程,这个方法的一个好处是各线程之间不必使用join来执行了,各个线程可以独立出来。
PriorityQueue的用法:
PriorityQueue<Integer> queue = new PriorityQueue<Integer>(11, new MyComparator());
queue.add(3);
queue.add(1);
queue.add(-2);
queue.add(4);
queue.add(6);
queue.add(9);
queue.add(2);
queue.offer(8);
while (!queue.isEmpty()) {
Log.v("zxy", queue.poll() + "");//9864321-2
}
public static class MyComparator implements Serializable, Comparator<Integer> {
@Override
public int compare(Integer lhs, Integer rhs) {
int value = lhs > rhs ? 1 : lhs < rhs ? -1 : 0;
return value;
}
}
上面这个示例就是优先队列的基本用法,它可以传入一个我们自定义的比较器,利用这个比较器我们可以自己定义队列中元素的顺序。其中compare()方法中的返回值:
1、>0:代表lhs>rhs
2、<0:代表rhs>lhs
3、==0:代表lhs==rhs
而PriorityQueue中有这么几个方法:
1、queue.poll():表示从队列中取出队首上的元素,且取出后remove掉这个元素
2、queue.peek():表示从队列中取出队首上的元素,且取出后不remove掉这个元素
3、queue.add():表示添加一个元素
4、queue.clear():表示清空队列
5、queue.remove():表示移除某个元素
6、queue.size():表示队列的size
利用优先队列实现多个线程顺序执行
final PriorityQueue<Thread> queue = new PriorityQueue<>(11, new MyThreadComparator());
queue.add(thread1);
queue.add(thread2);
queue.add(thread3);
queue.add(thread5);
queue.add(thread7);
queue.add(thread6);
queue.add(thread4);
boolean flag = false;
Thread mThread = null;
int i=0;
int size = queue.size();
while (!queue.isEmpty()) {
if(!flag){
mThread = queue.poll();
mThread.start();
flag = true;
i++;
}
if(mThread.getState()== Thread.State.TERMINATED && !queue.isEmpty()){
if(size==i){
break;
}
if(size==(i+1)){
mThread = queue.peek();
mThread.start();
i++;
}else {
mThread = queue.poll();
mThread.start();
i++;
}
}
}
public static class MyThreadComparator implements Serializable, Comparator<Thread> {
@Override
public int compare(Thread lhs, Thread rhs) {
int value = lhs.getPriority() < rhs.getPriority() ? 1 : lhs.getPriority() > rhs.getPriority() ? -1 : 0;
return value;
}
}
这里每创建一个线程我都给它设置了一个自带的优先级(其实这个只是一个标志,你也可以用任何东西作为标志,比如采用),用来表示该线程的优先级:
Thread thread1 = new Thread( new Runnable() {
@Override
public void run() {
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.v("zxy", "result—>thread1");
}
});
thread1.setPriority(3);
利用它做的一些效果:
Android中让多个线程顺序执行探究的更多相关文章
- Java中如何保证线程顺序执行
只要了解过多线程,我们就知道线程开始的顺序跟执行的顺序是不一样的.如果只是创建三个线程然后执行,最后的执行顺序是不可预期的.这是因为在创建完线程之后,线程执行的开始时间取决于CPU何时分配时间片,线程 ...
- T1,T2,T3 三个线程顺序执行
T1,T2,T3 三个线程顺序执行 现在有 T1.T2.T3 三个线程,你怎样保证 T2 在 T1 执行完后执行,T3 在 T2 执行完后执行?(T1->T2->T3) 这个线程问题通常会 ...
- c#线程顺序执行
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- Java中线程顺序执行
现有线程threadone.threadtwo和threadthree,想要的运行顺序为threadone->threadtwo->threadthree,应该如何处理?这里需要用到一个简 ...
- js中一个标签在按顺序执行没有被读取到时可以用window.onload
<%@LANGUAGE="JAVASCRIPT" CODEPAGE="65001"%> <!DOCTYPE html PUBLIC " ...
- java中怎么终止一个线程的执行----个人学习心得
参考了一下两个网站的介绍: ①:http://blog.csdn.net/liuhanhan512/article/details/7077601 ②:http://www.blogjava.net/ ...
- Android 中三种启用线程的方法
在多线程编程这块,我们经常要使用Handler(处理),Thread(线程)和Runnable这三个类,那么他们之间的关系你是否弄清楚了呢? 首先说明Android的CPU分配的最小单元是线程,Han ...
- Android中的进程与线程
四大组件都是运行在主线程中 1.前台进程:用户正在交互,相当于Activity执行了onResume方法 2.可见进程:用户失去了焦点,相当于Activity执行了onPause方法 3.服务进程:运 ...
- Android中不能在子线程中更新View视图的原因
这是一条规律,很多coder知道,但原因是什么呢? 如下: When a process is created for your application, its main thread is ded ...
随机推荐
- 一起聊聊什么是P问题、NP问题、NPC问题
概念 P问题:如果一个问题可以找到一个能在多项式的时间里解决它的算法,那么这个问题就属于P问题.通常NOI和NOIP不属于P类问题,我们常见到的一些信息奥赛的题目都是P问题. NP问题:可以在多项式的 ...
- (一)ROS系统入门 Getting Started with ROS 以Kinetic为主更新 附课件PPT
ROS机器人程序设计(原书第2版)补充资料 教案1 ROS Kinetic系统入门 ROS Kinetic在Ubuntu 16.04.01 安装可参考:http://blog.csdn.net/zha ...
- Servlet - 会话跟踪
Servlet 标签 : Java与Web 会话跟踪 HTTP本身是"无状态"协议,它不保存连接交互信息,一次响应完成之后即连接断开,下一次请求需要重新建立连接,服务器不记录上次连 ...
- Android Multimedia框架总结(十二)CodeC部分之OMXCodec与OMX事件回调流程
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52629449 前言:上篇文中分析 ...
- android的activity栈管理
在进行BlackBerry程序开发的时候,BlackBerry提供了一个管理Screen的栈,用来从任何地方来关闭位于最上一层的Screen,使用UiApplication.getUiApplicat ...
- 【移动开发】SparseArray替代HashMap
SparseArray是android里为<Interger,Object>这样的Hashmap而专门写的class,目的是提高效率,其核心是折半查找函数(binarySearch). p ...
- 与音频相关的技术知识点总结(Linux方向的开发)
几个术语和概念: 1. 关于PCM的 PCM是Pulse code modulation的缩写,它是对波形最直接的编码方式.它在音频中的地位可能和BMP在图片中的地位有点类似吧. Samp ...
- android 特卖列表倒计时卡顿问题
在Android的开发中,我们经常遇见倒计时的操作,通常使用Timer和Handler共同操作来完成.当然也可以使用Android系统控件CountDownTimer,这里我们封装成一个控件,也方便大 ...
- Android布局性能优化—从源码角度看ViewStub延迟加载技术
在项目中,难免会遇到这种需求,在程序运行时需要动态根据条件来决定显示哪个View或某个布局,最通常的想法就是把需要动态显示的View都先写在布局中,然后把它们的可见性设为View.GONE,最后在代码 ...
- Android异常:android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original
Android异常:android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that cr ...