1. Sleep:在线程内部使用sleep方法,可使当前线程从RUNNING状态进入Timed Wating状态;其他线程可以使用interrupt()方法,打断正在睡眠的线程并唤醒线程。这时sleep()方法会抛出InterruptedException异常;
2.yield: 让出线程,让当前线程从Running状态转化为Runnable就绪状态;但也存在,调用yield()之后CPU又重新调度了当前线程。
3.SetPriority(); 设置优先级,最小优先级为1,最大为10; 默认为5;设置优先级后,cpu也不是每次都会优先执行优先级高的线程,cpu调用线程取决于调度器调度。
4.join(): 会阻塞当前线程,并等待调用该方法的线程执行完毕;
4.1.join(long time): 在time时间内等待线程执行完毕。如果在时间内线程没有执行完毕,那么会解除阻塞的线程。如果time时间远超于调用join()线程执行时间,按实际执行时间结束;
5.Interrupt(): 当前线程(主线程)打断调用interrupt()方法的线程(t1),并赋予t1线程一个打断标记;但并不会结束t1线程;t1线程可使用该标记来决定是否结束自己。如果interrupt()打断的是线程的sleep(), wait(), join()方法时,不会给t1线程赋予一个打断标记;而是通过异常(Interrupted Exception)来说明线程被打断;
两阶段中止设置模式:如果检测到被打断,则处理好程序后退出线程;如果在sleep的时候被打断,则抛出打断异常,可在异常种处理程序;
对应code应用:
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "tc2")
public class TC2 {
public static void main(String[] args) throws InterruptedException {
TwoPhaseTermination tpt = new TwoPhaseTermination();
log.debug("开始监控...");
tpt.start();
Thread.sleep(3500);
tpt.stop();
log.debug("结束监控...");
}
}
@Slf4j(topic = "TwoPhaseTermination")
class TwoPhaseTermination{
private Thread monitor;
public void start(){
monitor = new Thread(()->{
while (true) {
Thread currentThread = Thread.currentThread();
if (currentThread.isInterrupted()) {
log.debug("料理后事");
break;
}
try {
Thread.sleep(1000);
log.debug("记录监控");
} catch (InterruptedException e) {
e.printStackTrace();
//重新设置打断标记,因为在sleep()时被打断不会设置打断标记,只会抛出异常;
currentThread.interrupt();
}
}
});
monitor.start();
}
public void stop() {
monitor.interrupt();
}
}
6.interrupted(); 判断打断标记,并设置设置为false, 如果isInterrupted()=true; LockSupport.park()不生效;所以可以用Thread.interrupted()方法判断打断标记,如果是True,获取后设置为False;这样子就不影响LockSupport.park()使用;Thread.interrupt()可以打断park();
7.守护线程:setDaemon(true); 如果其他线程都运行结束了,但守护线程还没运行完,这时守护线程被强制结束,程序完毕。
8.多线程的五种状态:
9.程序里多线程的六种状态:New, Runnable, Waiting, Timed_waiting, Terminated, Blocked; 其中线程为了获取IO资源在阻塞队列时,也是Runnable状态, sleep()是Timed_waiting, join()是waiting;