java 应用层:
有三种:
1、使用定时器进行操作,将你需要的操作在几秒后再开始执行
private void TimerDelay(int delayMsec){
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("这个run里面可以放你需要等待之后的操作");
}
};
Timer timer = new Timer();
timer.schedule(task,delayMsec);//delayMsec 微秒后执行TimeTask的run方法
}
2、使用handler 的postDelayed 操作方法,此方法的效果与用timer基本一样
private void postDelay(int delayMsec){
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
System.out.println("这个run里面可以放你需要等待之后的操作");
}
}, delayMsec);//delayMsec/1000 秒后执行Runnable中的run方法
}
3、直接使用sleep方法:
private void threadDelay(int delayMsec){
final int delay = delayMsec;
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(delay);
System.out.println("这个run里面可以放你需要等待的操作");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
以上三种方法使用效果是不是一样的呢?
我们可以从原理上进行分析,第一种是一种定时器的操作,相当于我把一个操作放在未来的定时器到达的时刻进行执行,这个方法时间会比较准确;
第二种是使用handler,了解handler原理我们就知道,postDelayed 方法实际底下调用的是sendMessageDelayed方法,而sendMessageDelayed 方法
底下调用的是sendMessageAtTime,请注意,sendMessageAtTime()函数里面用的是SystemClock.uptimeMillis(),它是获取系统从开机启动到现在的时间,期间不包括休眠的时间,
这里获得到的时间是一个相对的时间,而不是通过获取当前的时间(绝对时间)。而之所以使用这种方式来计算时间,而不是获得当前currenttime来计算,在于handler会受到阻塞,
挂起状态,睡眠等,这些时候是不应该执行的;如果使用绝对时间的话,就会抢占资源来执行当前handler的内容,显然这是不应该出现的情况,所以要避免。
另外,因为handler使用的是queue机制,所以在有更高优先级立马执行的任务插入到这个queue里面来,也会影响你的delayed queue的时效性。
所以在使用第二种方法的就要注意是不是你想要的时效性问题。
第三种就简单了,这种方法一般使用在一些顺序执行同时又可以进行睡眠的线程任务中使用,时效性比第二种高,但因为是睡眠等待,所以有可能会有资源被其他线程抢占的问题。
C++ 系统层:
两种:
方法1:
void delay_msec(int msec)
{
clock_t now = clock();
while(clock()-now < msec);
}
此方法是一种忙等,线程会一直在这个地方,而不能做其他事情。
方法2:
#include <unistd.h>
sleep(sec);
此方法的单位是秒,相当于让线程进行睡眠等待,不占用CPU资源。
kernel 内核层:
1、msleep(int msec)方法
2、mdelay(int msec)方法
msleep是一种睡眠等待,意思就是说在执行该方法的线程是可以进行休眠的,不用占用CPU资源,CPU可以转而去做其他的
而mdelay是一种忙等,必须一直占用CPU,在使用过程中,要根据实际场景需求区分使用,否则可能会出现异常或者达不到你想要的效果。