一、线程常见方法
- start:运行线程,调用run
- run:定义线程的任务
- join:当前线程等待指定线程结束,然后继续执行后续任务
- getId:获取线程唯一id
- getName:获取线程名
- getPriority:获取线程优先级
- getState:获取线程状态
- isInterrupted:判断是否被打断
- isAlive:判断线程是否存活
- interrupt:打断线程,如果打断的是正在运行的线程,会设置打断标记,即为true;如果是处于sleep、wait等的线程则会抛出异常,并清除打断标记,即为flase。
- interrupted:判断当前线程是否被打断,会清除打断标记
- currentThread:获取当前正在执行的线程
- sleep:让当前线程睡眠多少毫秒
- yield:提示线程调度器让出当前线程(并不总是有用,只是提示)
- 线程优先级会提示调度器优先调度该线程,但它仅仅在CPU比较忙的时候有用
- 当CPU闲时,优先级几乎没有作用
二、join和interrupt
- join:等待某线程执行完成,然后继续执行后续任务
@Test
public void test6() throws InterruptedException {
Thread thread1=new Thread("t1"){
public void run(){
try {
log.info("执行中....");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread1.start();
thread1.join();
log.info("执行完成");
}
- interrupt:打断线程,仅修改打断标记
- 打断sleep、wait、join的线程,会清空打断状态,即isInterrupted()的值变为false
- 打断正常运行的线程,则会将打断标记,即isInterrupted()的值改为true,但不会真的打断线程
interrupt的应用:两阶段终止模式
@Test
public void test5() throws InterruptedException {
testThread=new Thread(()->{
while(true){
Thread currentThread=Thread.currentThread();
if(currentThread.isInterrupted()){
log.info("料理后事....");
break;
}
try {
log.info("执行正常逻辑");
Thread.sleep(1000);
log.info("执行监控记录");
} catch (Exception e) {//当捕捉到异常时,标记会被重置为false
e.printStackTrace();
currentThread.interrupt();//所以需要重新设置打断标记,不然无法退出循环
}
}
});
testThread.start();
Thread.sleep(3500);
testThread.interrupt();
}
三、主线程和守护线程
- Java的主线程简单来说即顺着main函数走下去的部分
- 守护线程指所有线程都运行结束才会结束的进程
- 同时也意味着只要其他非守护进程运行结束了,即使守护线程的代码没有执行完,也会强制结束
- 例如:Java中的垃圾回收线程,Tomcat中的Acceptor和Poller线程
四、线程的五种状态(从操作系统层面来描述)
- 初始状态:仅创建了线程对象,还未与操作系统线程关联
- 可运行状态(就绪状态):指已经与操作系统线程关联,可以由CPU调度执行
- 运行状态:指获取了CPU时间片正在运行中的状态
- 阻塞状态:需要BIO读写文件或等待其他资源时的状态
- 终止状态:线程执行完毕,生命周期结束时的状态
五、线程的六种状态(从Java API层面来描述)
- NEW:新建状态,即new了一个线程对象,写了run方法,但还没start的时候
- RUNNABLE:可运行状态,包括就绪、运行、部分阻塞等,即开始start之后
- TERMINATED:结束状态,线程执行完毕
- BLOCKED、WAITING、TIMED_WAITING:调用不同的API,例如wait等方法进入的状态