线程常用的方法

83 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第19天,点击查看活动详情

join()

public final synchronized void join(long millis) throws InterruptedException {
    long base = System.currentTimeMillis();
    long now = 0;
    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }
    if (millis == 0) {
        while (isAlive()) {
            wait(0);
        }
    } else {
        while (isAlive()) {
            long delay = millis - now;
            if (delay <= 0) {
                break;
            }
            wait(delay);
            now = System.currentTimeMillis() - base;
        }
    }
}

if (millis < 0) { throw new IllegalArgumentException("timeout value is negative");} 判断超时时间是否小于 0,如果小于0,则会抛出IllegalArgumentException异常

if (millis == 0) { while (isAlive()) { wait(0); } } millis 等于 0 表示无限等待,直到线程执行完为止 isAlive判断子线程是否为活跃线程,是则一直等待

wait(delay); 可以看出,join()方法底层还是通过wait()实现的。

在实际的使用中,如果在main方法中启用了一个新的线程,并且在主线程中调用了join()方法,则实际的效果则会表现为: 主线程会先等子线程执行完成后才继续执行。

yield()

public static native void yield();

yield()方法是调用的java本地方法,底层是由C或者C++实现的。

yield()方法含义是:给线程调度器一个当前线程愿意出让 CPU 使用权的信息。但是线程调度器并不是一定会立马响应这个请求,甚至不会响应。

sleep()

public static native void sleep(long millis) throws InterruptedException;

sleep使当前线程(即调用sleep方法的线程暂停一段时间),给其它的线程运行的机会,而且是不考虑其它线程的优先级的,而且不释放资源锁,也就是说如果有synchronized同步块,其它线程仍然是不能访问共享数据的

当线程执行了sleep方法之后,线程将转入到睡眠状态,直到时间结束

sleep方法需要抛出或者捕获异常,因为线程在睡眠中可能被打断,

wait()和wait(time)

wait()的作用是让当前线程进入等待状态,wait()也会让当前线程释放它所持有的锁。 直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,当前线程才会被唤醒进入就绪状态


public final void wait() throws InterruptedException {
    wait(0);
}
    
public final native void wait(long timeout) throws InterruptedException;

wait() 实现也是调用的wait(long timeout)方法,时间传入的是0

wait(long timeout)方法底层是调用的java本地方法,由C或者C++实现。