线程中常见方法的使用
常见方法简介
-
start()
启动一个新线程,在新的线程 运行 run 方法 中的代码
start 方法只是让线程进入就绪,里面代码不一定立刻 运行(CPU 的时间片还没分给它)。每个线程对象的 start方法只能调用一次,如果调用了多次会出现 IllegalThreadStateException
-
run()
新线程启动后会
调用的方法
如果在构造 Thread 对象时传递了 Runnable 参数,则 线程启动后会调用 Runnable 中的 run 方法,否则默 认不执行任何操作。但可以创建 Thread 的子类对象, 来覆盖默认行为 -
join()
等待线程运行结 束
join(long n)
等待线程运行结 束,最多等待 n 毫秒
-
getId()
获取线程长整型 的 id
id 唯一 -
getName()
获取线程名 -
setName(String)
修改线程名 -
getPriority()
获取线程优先级 -
setPriority(int)
修改线程优先级
java中规定线程优先级是1~10 的整数,较大的优先级 能提高该线程被 CPU 调度的机率 -
getState()
获取线程状态
Java 中线程状态是用 6 个 enum 表示,分别为: NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED
判断是否被打 断, -
isInterrupted()
不会清除 打断标记 -
isAlive()
线程是否存活
(还没有运行完
毕) -
interrupt()
打断线程
如果被打断线程正在 sleep,wait,join 会导致被打断 的线程抛出 InterruptedException,并清除打断标记 ;如果打断的正在运行的线程,则会设置 打断标 记 ;park 的线程被打断,也会设置打断标记 -
interrupted()
static
判断当前线程是 否被打断
会清除 打断标记
start() 和run()方法
区别:调用start()方法是启动线程的正确方法,而调用run()方法仅仅是调用了一个普通方法
- 直接调用 run 是在主线程中执行了 run,没有启动新的线程
- 使用 start 是启动新的线程,通过新的线程间接执行 run 中的代码
sleep() 和 yield()方法
sleep
- 调用 sleep 会让当前线程从 Running 进入 Timed Waiting 状态(阻塞)
- 其它线程可以使用 interrupt 方法打断正在睡眠的线程,这时 sleep 方法会抛出 InterruptedException 3. 睡眠结束后的线程未必会立刻得到执行
- 建议用 TimeUnit 的 sleep 代替 Thread 的 sleep 来获得更好的可读性
yield
- 调用 yield 会让当前线程从 Running 进入 Runnable 就绪状态,然后调度执行其它线程
- 具体的实现依赖于操作系统的任务调度器
线程优先级
线程优先级会提示(hint)调度器优先调度该线程,但它仅仅是一个提示,调度器可以忽略它 如果 cpu 比较忙,那么优先级高的线程会获得更多的时间片,但 cpu 闲时,优先级几乎没作用
join()和join(n)方法
t.join();
//调用join方法,等待线程t执行完毕
t.join(1000);
//等待 t 线程,等待时间是1000毫秒,若1000ms后t还未执行完毕,也会继续向下执行。
**1. 在哪个线程中调用join()方法,该线程就会等待。**比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。
- 在主线程中调用t.join()相当于主线程sleep()直到t线程执行结束
- 一旦join()的线程执行结束就会立即执行后续代码。⚠️若有多个线程join() 等待时间通过取决于最长的那个线程,因为在多核cpu中多个线程是并行执行的。
interrupt() 方法
-
打断 sleep,wait,join 的线程这几个方法都会让线程进入阻塞状态,打断 sleep 的线程, 会清空打断状态
-
打断正常运行的线程 打断正常运行的线程, 不会清空打断状态
-
⚠️区分另外一个interrupted()方法会清除打断标记
两阶段终止模式
@Slf4j(topic = "c.twophaseterminal")
public class TwoFhaseTerminal {
public static void main(String[] args) throws InterruptedException {
Monitor monitor = new Monitor();
monitor.start();
Thread.sleep(1500);
monitor.stop();
}
}
@Slf4j(topic = "c.monitor")
class Monitor {
private Thread monitorThread;
public void start() {
monitorThread = new Thread(() -> {
while (true) {
Thread currentThread = Thread.currentThread();
if (currentThread.isInterrupted()) {
log.debug("料理后事");
break;
}
try {
log.debug("监控ing");
Thread.sleep(1000);
} catch (InterruptedException e) {
// 在sleep时被打断会抛出InterruptedException异常,并清除
// 打断标记,则打断执行失败,不能打断线程的执行
e.printStackTrace();
currentThread.interrupt(); // 目的是设置打断标记
}
}
});
monitorThread.start();
}
public void stop() {
monitorThread.interrupt();
}
}
过时方法
方法名 | static | 功能说明 |
---|---|---|
stop() | 停止线程运行 | |
suspend() | 挂起(暂停)线程运行 | |
resume() | 恢复线程运行 |
这些方法已过时,容易破坏同步代码块,造成线程死锁,尽量不要使用!
项目完整代码
关住公Z号【离离原上狍】回复Java并发获取链🔗接
有问题欢迎评论和私信,有错误请指出,共同学习共同进步!