线程的常用方法
1 run()和start()
示例代码
import lombok.extern.slf4j.Slf4j;
/**
* @author : look-word
* 2022-08-13 15:31
**/
@Slf4j
public class C1_RunAndStart {
public static void main(String[] args) {
Thread thread = new Thread() {
@Override
public void run() {
log.info("当前线程 {} ", Thread.currentThread().getName());
}
};
thread.run();
thread.start();
}
}
2 sleep
- 调用 sleep 会让当前线程从 Running 进入 Timed Waiting 状态(阻塞)
- 其它线程可以使用 interrupt 方法打断正在睡眠的线程,这时 sleep 方法会抛出 InterruptedException
- 睡眠结束后的线程未必会立刻得到执行
- 建议用 TimeUnit 的 sleep 代替 Thread 的 sleep 来获得更好的可读性
3 yield
- 调用 yield 会让当前线程从 Running 进入 Runnable 就绪状态,然后调度执行其它线程
- 具体的实现依赖于操作系统的任务调度器
4 join
示例代码
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
/**
* @author : look-word
* 2022-08-13 16:34
**/
@Slf4j
public class C3_Join {
static int num = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
try {
TimeUnit.MILLISECONDS.sleep(1000); // 使线程睡眠
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
num =10;
},"t1");
t1.start();
// t1.join();
log.info("num :{}",num);
}
}
// 执行结果 会先输出num的值 程序不会立马结束运行。(异步)
16:50:39.034 [main] INFO c_常用方法.C3_Join - num :0
// 可以看到 上面的join方法是注释掉的。 我们给它放开之后的执行结果。会等待(同步)
16:52:40.783 [main] INFO c_常用方法.C3_Join - num :10
示例代码2
Thread t1 = new Thread(() -> {
try {
TimeUnit.MILLISECONDS.sleep(2000); // 使线程睡眠
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
num =10;
},"t1");
log.info("start。。。");
t1.start();
t1.join(1000); // 等待具体的毫秒数
log.info("num :{}",num);
5 interrupt
示例代码1
Thread t1 = new Thread(() -> {
try {
Thread.sleep(1000); // 睡眠t1线程
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
t1.start();
Thread.sleep(10); // 睡眠主线程
t1.interrupt(); // 打断t1线程
log.debug("{}的打断状态{}", t1.getName(), t1.isInterrupted());
示例代码2
/**
* 打断正常运行的线程
*/
private static void test2() throws InterruptedException {
Thread t1 = new Thread(() -> {
while (true){
log.info("{} 线程 running。。",Thread.currentThread().getName());
if (Thread.currentThread().isInterrupted()){ // 是否被打断
break;
}
}
},"t1");
t1.start();
t1.interrupt(); // 打断线程
log.debug("{}的打断状态{}", t1.getName(), t1.isInterrupted());
}
终止模式之两阶段终止模式
代码实现
import lombok.extern.slf4j.Slf4j;
/**
* @author : look-word
* 2022-08-13 18:15
**/
public class 两极阶段终止模式 {
public static void main(String[] args) throws InterruptedException {
Monitor monitor = new Monitor();
monitor.start(); // 启动监控程序
Thread.sleep(3500);
monitor.stop(); // 停止监控程序
}
}
@Slf4j
class Monitor{ // 监控程序
Thread monitor;
// 启动监控线程
public void start(){
monitor = new Thread(() ->{
while (true){
Thread current = Thread.currentThread();
if (current.isInterrupted()){
log.error("料理后事 结束!");
break;
}
try {
Thread.sleep(1000);
log.debug("执行监控记录!!");
} catch (InterruptedException e) {
// 重写设置打断
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
});
monitor.start(); // 启动监控线程
}
// 停止监控线程
public void stop(){
monitor.interrupt(); // 打断线程
}
}
6 pack
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.LockSupport;
/**
* join 会使所有线程等待 (同步)
* LockSupport.park(); 只会使当前线程等待 (异步)
* @author : look-word
* 2022-08-13 21:02
**/
@Slf4j
public class C5_Park {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
log.debug("pack...");
log.debug("打断状态前:{}", Thread.currentThread().isInterrupted());
LockSupport.park(); // 使当前线程等待
log.debug("unPark...");
log.debug("打断状态后:{}", Thread.currentThread().isInterrupted());
}, "t1");
t1.start();
Thread.sleep(500);
// 这里会等500ms 立即执行
log.debug("打断状态:{}", Thread.currentThread().isInterrupted());
t1.interrupt(); // 打断线程
}
}
结果
21:17:46.920 [t1] DEBUG c_常用方法.C5_Park - pack...
21:17:46.923 [t1] DEBUG c_常用方法.C5_Park - 打断状态前:false
21:17:47.422 [main] DEBUG c_常用方法.C5_Park - 打断状态:false
21:17:47.422 [t1] DEBUG c_常用方法.C5_Park - unPark...
21:17:47.422 [t1] DEBUG c_常用方法.C5_Park - 打断状态后:true