sleep是Thread中的函数,JDK中对应的源码如下:
public static void sleep(long millis) throws InterruptedException {
Thread.sleep(millis, 0);
}
public static void sleep(long millis, int nanos)
throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("millis < 0: " + millis);
}
if (nanos < 0) {
throw new IllegalArgumentException("nanos < 0: " + nanos);
}
if (nanos > 999999) {
throw new IllegalArgumentException("nanos > 999999: " + nanos);
}
// The JLS 3rd edition, section 17.9 says: "...sleep for zero
// time...need not have observable effects."
if (millis == 0 && nanos == 0) {
// ...but we still have to handle being interrupted.
if (Thread.interrupted()) {
throw new InterruptedException();
}
return;
}
long start = System.nanoTime();
long duration = (millis * NANOS_PER_MILLI) + nanos;
Object lock = currentThread().lock;
// Wait may return early, so loop until sleep duration passes.
synchronized (lock) {
while (true) {
sleep(lock, millis, nanos);
long now = System.nanoTime();
long elapsed = now - start;
if (elapsed >= duration) {
break;
}
duration -= elapsed;
start = now;
millis = duration / NANOS_PER_MILLI;
nanos = (int) (duration % NANOS_PER_MILLI);
}
}
}
private static native void sleep(Object lock, long millis, int nanos)
throws InterruptedException;
tips:long now = System.nanoTime();它是一个更精确的时间表达,us微秒级别的,常用于精确计时器的使用,但是它的值不是固定的,可以代表过去的某一时刻(正值),也可以代表未来的某一时刻(负值),可以用来倒计时时间的统计.
1.sleep 方法需要捕获底层抛出的InterruptedException异常,sleep方法在倒计时区间内会让出cpu资源给其他线程,等倒计时结束后自动恢复运行状态.
class Thread1 implements Runnable {
@Override
public void run() {
Log.e(TAG, "enter thread1.......");
Log.e(TAG, "thread1 is waiting...");
try {
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
Log.e(TAG, "thread1 is going on ....");
Log.e(TAG, "thread1 is over.....");
}
}
class Thread2 implements Runnable {
@Override
public void run() {
Log.e(TAG, "enter thread2....");
Log.e(TAG, "thread2 is sleep....");
Log.e(TAG, "thread2 is going on....");
Log.e(TAG, "thread2 is over....");
}
}
public void testSleep() {
new Thread(new Thread1()).start();
new Thread(new Thread2()).start();
}
如下的输出验证了上面1中的结论:
2.在调用sleep()方法的过程中,线程不会释放对象锁.
class Thread1 implements Runnable {
@Override
public void run() {
synchronized (object) {
Log.e(TAG, "enter thread1.......");
Log.e(TAG, "thread1 is waiting...");
try {
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
Log.e(TAG, "thread1 is going on ....");
Log.e(TAG, "thread1 is over.....");
}
}
}
class Thread2 implements Runnable {
@Override
public void run() {
synchronized (object) {
Log.e(TAG, "enter thread2....");
Log.e(TAG, "thread2 is sleep....");
Log.e(TAG, "thread2 is going on....");
Log.e(TAG, "thread2 is over....");
}
}
}
public void testSleep() {
new Thread(new Thread1()).start();
new Thread(new Thread2()).start();
}
输出验证了2中的结论:
3.wait()方法属于Object对象的方法,当调用wait()方法的时候线程会放弃对象锁,直到等到别的线程调用notify()/notifyAll()方法时本线程才会放入对象锁定池等待执行,否则不会执行下去。
Object object = new Object();
class Thread1 implements Runnable {
@Override
public void run() {
synchronized (object) {
Log.e(TAG, "enter thread1.......");
Log.e(TAG, "thread1 is waiting...");
try {
object.wait(); //调用wait()方法,线程会放弃对象锁,进入等待此对象的等待锁定池
} catch (Exception e) {
e.printStackTrace();
}
Log.e(TAG, "thread1 is going on ....");
Log.e(TAG, "thread1 is over.....");
}
}
}
class Thread2 implements Runnable {
@Override
public void run() {
synchronized (object) {
Log.e(TAG, "enter thread2....");
Log.e(TAG, "thread2 is sleep....");
//只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。
object.notify();
Log.e(TAG, "thread2 is going on....");
Log.e(TAG, "thread2 is over....");
}
}
}
public void testSleep() {
new Thread(new Thread1()).start();
new Thread(new Thread2()).start();
}
输出验证了3中的结论: