持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情
线程类提供了很多常用的方法,使用他们可以完成线程之间的协作或者使线程中断,提前结束生命周期。
sleep
sleep(millisec)方法会使当前正在执行的线程休眠millisec毫秒。
Thread thread = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName());
e.printStackTrace();
}
});
thread.start();
thread.interrupt();
sleep方法可能会抛出InterruptedException,但是异常不能跨线程传播,所以需要在该线程进行处理。
yield
yield()会使当前线程让出 CPU 执行时间片,重新与其他线程一起竞争CPU资源。
Thread[] threads = new Thread[2];
for (int i=0;i<2;i++){
int index=i;
threads[i] = new Thread(() -> {
System.out.println("threads"+index+":"+1);
Thread.yield();
System.out.println("threads"+index+":"+2);
});
threads[i].start();
}
多次运行之后记过可能输出:
threads0:1
threads0:2
threads1:1
threads1:2
说明yield()方法即使让出了执行权,但是也可能再次被选中。
interrupt
interrupt()方法可以中断当前线程,如果当前线程处于阻塞等待情况,则会抛出InterruptedException并且提前结束线程,就如同sleep()方法中的示例一样,当调用sleep()方法之后在调用它的interrupt()方法就会提前结束线程。
interrupted
前面说到interrupt()方法会使处于阻塞等待等情况的线程中断并且抛出异常,但是如果一个线程生命周期很长并且没有执行sleep()等抛出InterruptedException的操作,那么interrupt()方法就不能提前结束当前线程,但是它会设置一个中断标记,此时interrupted()返回true.
Thread thread = new Thread() {
@Override
public void run() {
while (!isInterrupted()) {
System.out.println("running");
}
System.out.println("interrupted");
}
};
thread.start();
Thread.sleep(1);
thread.interrupt();
输出
running
running
interrupted
join
在线程中调用另一个线程的 join() 方法,会将当前线程挂起。等到另一个线程执行完成之后才会变为就绪状态,等待执行。
static String publicValue = "默认值";
public static void main(String[] args) {
Thread thread = new Thread(() -> {
try {
Thread.sleep(1000);
publicValue = "被第一个线程重新赋值";
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
new Thread(() -> {
System.out.println(publicValue);
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(publicValue);
}).start();
}
结果输出
默认值
被第一个线程重新赋值
wait
sleep 导致当前线程休眠但是不会释放占有的锁,但是wait()方法会释放锁。释放完锁之后,其他线程就可以进入对象的同步方法或者同步代码快中,调用notify()或者notifyAll()唤醒该线程。wait()是Object的方法,而sleep()是Thread的方法。