JUC并发编程——常用方法

sleep()

public void testSleepAndYield() {
	Thread t1 = new Thread(() -> {
        try {
            log.debug("t1-sleep...");
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }, "t1");

    log.debug("t1 start 前的状态:{}",t1.getState());   // NEW  创建
    t1.start();
    log.debug("t1 start 后的状态:{}",t1.getState());   // RUNNABLE 就绪 => t1 线程刚创建,还未 sleep

    // 让主线程等待一会儿,等 t1 线程 sleep 时,查看 t1 线程的状态
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }

    log.debug("t1 sleep 时的状态:{}",t1.getState());   // TIMED_WAITING 阻塞
}   
16:34:01:196 [main] c.Test2 - t1 start 前的状态:NEW
16:34:01:198 [main] c.Test2 - t1 start 后的状态:RUNNABLE
16:34:01:199 [t1] c.Test2 - t1-sleep...
16:34:01:708 [main] c.Test2 - t1 sleep 时的状态:TIMED_WAITING
  1. 调用 sleep 会让当前线程从 Running 进入 Timed Waiting 状态(阻塞)
  2. 其它线程可以使用 interrupt 方法打断正在睡眠的线程,这时 sleep 方法会抛出 InterruptedException
  3. 睡眠结束后的线程未必会立刻得到执行
  4. 建议用 TimeUnit 的 sleep 代替 Thread 的 sleep 来获得更好的可读性

join()

	static int i = 0;
    public static void main(String[] args) throws InterruptedException {
        test1();
    }
	private static void test1() throws InterruptedException {
       Thread t1 = new Thread(() -> {
           try {
               Thread.sleep(1000);
               i = 10;
           } catch (InterruptedException e) {
               throw new RuntimeException(e);
           }
       }, "t1");
       t1.start();
       // 让当前线程等待 t1 线程结束
       t1.join();
       log.debug("结果为:{}", i);
   }

未调用 join 方法

17:04:04:422 [main] c.TestJoin - 结果为:0

调用 join 方法

17:01:37:312 [main] c.TestJoin - 结果为:10

等待当前线程运行结束

join(long n):等待线程运行结束,最多等待 n 毫秒。

Interrupt()

打断 sleep,wait,join 的线程,这几个方法都会让线程进入阻塞状态

打断 sleep 的线程, 会清空打断状态

@Test
public void testInterrupt() throws InterruptedException {
    Thread t1 = new Thread(() -> {
        try {
            log.debug("sleeping");
            // 让 t1 线程进入休眠,外部线程尝试 interrupt
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }, "t1");

    t1.start();
    Thread.sleep(1000);
    log.debug("interrupt");
    t1.interrupt();
    log.debug("是否被打断:{}",t1.isInterrupted());
}

可以看到t1 sleep 一秒后已经被打断了,且抛出了 InterruptedException: sleep interrupted异常,但是查询t1的打断状态缺失,显示未打断,说明 sleep 时线程被 interrupt 后,清除了 interrupt 的状态。

打断正常运行的线程,不会清除打断状态

private static void test1() {
    Thread t1 = new Thread(() -> {
        while (true){
            Thread current = Thread.currentThread();
            // 查看当前线程是否被打断
            boolean interrupted = current.isInterrupted();
            if (interrupted){
                log.debug("t1-interrupt...");
                break;
            }
        }
    }, "t1");
    t1.start();

    log.debug("interrupt");
    t1.interrupt();
    log.debug("是否被打断:{}",t1.isInterrupted());
}

注意 interrupt() 和 isInterrupted() 方法的区别

interrupted()isInterrupted()
static
判断当前线程是否被打断判断当前线程是否被打断
会清除 打断标记不会清除 打断标记
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值