线程常用方法使用

本文详细探讨了Java线程的sleep、yield、join方法以及中断机制。通过示例代码展示了如何在线程中使用这些方法,包括线程被打断时的行为、线程状态的检查以及中断标志的处理。此外,还分析了park方法与interrupted()方法在中断处理中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Sleep

在这里插入图片描述

/**
     * 验证当sleep时,线程被打断
     * @throws InterruptedException
     */
    @Test
    public void test1() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
                System.out.println("子线程执行了");
            } catch (InterruptedException e) {
                e.printStackTrace();           //当线程t1被打断时,就会走到catch里,“子线程执行了”这条语句不会输出了
            }
        });
        t1.start();
        TimeUnit.SECONDS.sleep(1);
        t1.interrupt();     //通过main线程打断睡眠中的t1线程
    }


    /**
     * 验证线程在sleep的时候,线程状态是什么
     * @throws InterruptedException
     */
    @Test
    public void test2() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t1.start();
        TimeUnit.SECONDS.sleep(1);   //睡眠1s是为了更好的测试,让t1先执行,在t1睡眠的过程中通过main线程调用t1的getstate方法来查看状态
        System.out.println(t1.getState());  //TIMED_WAITING,当t1线程睡眠时,他的状态就是TIMED_WAITING
    }

yield

在这里插入图片描述
yield会让当前线程让出cpu的使用权,但是可能出现让出使用权后,又获取到cpu的时间片

sleep与yield区别

当执行这两个方法后,都会释放cpu使用权,yield会重新竞争cpu使用权,但是sleep需要等待设置的超时时间完成之后才会竞争

join

/**
     * 验证join的使用
     * @throws InterruptedException
     */
    int a=1;
    @Test
    public void test3() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            a = 10;
        });
        t1.start();
        t1.join();    //直到t1线程执行完毕,后面的代码才会执行,这就是join的作用
        System.out.println(a);
    }

interrupt

  • isInterrupted()方法,返回打断标记状态
    1)打断阻塞的线程(一般是调用了sleep,wait,join方法。join底层就是wait),会把打断标记复位

    /**
       * 当一个线程处于被阻塞状态或者试图执行一个阻塞操作时,使用Thread.interrupt()方式中断该线程,
       * 注意此时将会抛出一个InterruptedException的异常,同时中断状态将会被复位(由中断状态改为非中断状态)
       * @throws InterruptedException
       */
      @Test
      public void test4() throws InterruptedException {
          Thread t1 = new Thread(() -> {
              try {
                  System.out.println("t1............sleep");
                  TimeUnit.SECONDS.sleep(5);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          });
          t1.start();
          TimeUnit.SECONDS.sleep(1);
          System.out.println("interrupt..........");
          t1.interrupt();
          boolean interrupted = t1.isInterrupted();
          System.out.println("打断标记为:"+interrupted);    //false
      }
    

    2)打断正常的线程

 /**
     * 验证interrupt打断正常的线程时,
     * 注意打断线程并不是线程就停止了,线程不会有任何的响应
     * 想要停止,就必须使用isInterrupted的返回值来判断是否结束线程
     * @throws InterruptedException
     */
     public class InterruptThread2 {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread() {
            @Override
            public void run() {
                while (true) {
                    System.out.println("未被中断");
                }
            }
        };
        t1.start();
        TimeUnit.SECONDS.sleep(2);
        t1.interrupt();
 
        /*
         * 输出结果(无限执行):
         未被中断
         未被中断
         未被中断
         ......
         */
 
        // 虽然我们调用了interrupt方法,但线程t1并未被中断,因为处于非阻塞状态的线程需要我们手动进行中断检测并结束程序
    }
}

park方法以及interrupted()方法

package com.che.springbootdemo.thread;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

/**
 * @author cyh
 * @Description
 * @date 2022/4/10 20:20
 */
@Slf4j
public class Park {

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            log.debug("park....");
            LockSupport.park();
            log.debug("unpark111111.......");
            log.debug("打断状态:{}", Thread.currentThread().isInterrupted());
            LockSupport.park();  //此处已经park住了,但是后面的代码还是会执行,
            // 因为上面的打断标记已经是true了,所以下面n次park都会执行,如果想park住,
            // 可以将Thread.currentThread().isInterrupted()替换成Thread.interrupted(),
            //他的作用就是返回打断标记,并将标记重新置为false,当打断标记为false时,就能park住
            log.debug("unpark22222.......");
        }, "t1");
        t1.start();
        TimeUnit.SECONDS.sleep(1);
        t1.interrupt();
    }
}

/**
     * 运行结果
     * 20:27:02.425 [t1] DEBUG com.che.springbootdemo.thread.Park - park....
     * 20:27:03.423 [t1] DEBUG com.che.springbootdemo.thread.Park - unpark111111.......
     * 20:27:03.423 [t1] DEBUG com.che.springbootdemo.thread.Park - 打断状态:true
     * 20:27:03.424 [t1] DEBUG com.che.springbootdemo.thread.Park - unpark22222.......
     */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值