【学习笔记】Java中线程的常见操作


前言

本文介绍 Java 线程中常见的方法,并给出对应的示例,最后简单介绍不推荐使用的方法。


一、常见方法一览

方法名static说明注意
start()启动一个新线程,在新的线程运行 run 方法中的代码start 方法只是让线程进入就绪,里面代码不一定立刻运行(CPU 的时间片还没分给它)。每个线程对象的 start 方法只能调用一次,如果调用了多次会出现IllegalThreadStateException
run()新线程启动后会调用的方法如果在构造 Thread 对象时传递了 Runnable 参数,则线程启动后会调用 Runnable 中的 run 方法,否则默认不执行任何操作。但可以创建 Thread 的子类对象,来覆盖默认行为
join()等待线程运行结束
join(long n)等待线程运行结束,最多等待 n 毫秒
isInterrupted()判断是否被打断不会清除 打断标记
interrupt()打断线程如果被打断线程正在 sleep,wait,join 会导致被打断的线程抛出 InterruptedException,并清除 打断标记;如果打断的正在运行的线程,则会设置 打断标记;park 的线程被打断,也会设置 打断标记
interrupted()static判断当前线程是否被打断会清除 打断标记
sleep(long n)static让当前执行的线程休眠 n 毫秒,休眠时让出 CPU 的时间片给其它线程
yield()static提示线程调度器让出当前线程对 CPU 的使用主要是为了测试和调试

二、常见方法示例

1. join 方法

join 方法的作用是让当前线程进入阻塞状态 且不释放 Object 的锁,等待join的线程执行完毕 进入到 TERMINATED 状态之后,再回到就绪状态,继续完成之前的任务。

join 方法常用的有两个重载方法:join()join(long ms)

其中带参数的 join 方法表示的是,不用一定得等待到 join 的线程执行完毕,如果已经超过了给定的 ms 毫秒的话,重新进入就绪状态争抢CPU资源。

join 方法的应用案例就是同步,如果当前线程的执行需要依赖其他线程执行完之后的结果,那么我们就可以调用 join 方法让别的线程先运行。

public class JoinDemo implements Runnable{
    @Override
    public void run() {
        try {
            System.out.println("我是子线程我先睡一秒");
            Thread.sleep(1000);
            System.out.println("我是子线程我睡完一秒了");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new JoinDemo());
        thread.start();
        thread.join();

        System.out.println("如果不加join方法,我就会先打印出来。");
    }
}

2. sleep 方法

Thread.sleep(long ms),它的作用是让当前的线程睡眠指定的时间,进入 TIME_WAITTING 状态,在睡眠的期间该线程会释放CPU资源让其他线程去使用CPU,但不会释放同步监视器(锁)。

3. yield 方法

Thread.yield(),它的作用是让当前的线程放弃CPU资源但不会释放锁,并重新进入 RUNNABLE 状态抢夺CPU资源。

注意:JVM并不一定会同意线程的让步请求,所以通常在生产环境中很少使用该方法。

4. wait 方法

wait 方法的作用是让当前线程释放所有资源(包括CPU资源和锁),进入 WAITTING 状态,在此状态下的线程是不能够自我唤醒的,只能等待其他线程调用 notify 或者 notifyAll 唤醒该线程,被唤醒的线程不会立马获得锁,而是进行就绪状态等待系统的调度。

注意:

  • wait 方法必须在 synchronized 关键字标识的代码块或者方法中调用。
  • 调用 wait 方法的线程必须拥有同步监视器(锁)。

wait 方法有两种形式:Object.wait()Object.wait(long ms)

对于有参的 wait 方法,该线程会进入 TIME_WAITTING 状态,进入该状态的线程可以被其他线程唤醒或者时间超时自动唤醒。

5. notify 和 notifyAll 方法

Object.notify 方法的作用是唤醒等待队列(WAITTING 状态下或者 TIME_WAITTING 状态下)中的某个线程。

Object.notifyAll 方法则是唤醒等待队列(WAITTING 状态下或者 TIME_WAITTING 状态下)中的所有线程

6. interrupt 方法

interrupt() 方法用于向一个线程发送一个中断请求并将线程的中断标志设置为 true,接受到中断请求的线程可以在合适的时候处理这个中断请求,或者完全不进行处理。

  • isInterrupted():判断当前线程是否已经中断了。不会清空中断状态。
  • interrupted():判断当前是否已经中断了,会清空中断状态

6.1 打断正常运行的线程

public class InterruptDemo02 {
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            while (true) {
                log.debug("I'm running!");
                boolean interrupted = Thread.currentThread().isInterrupted();
                if (interrupted) {
                    log.debug("我来处理中断请求了");
                    break;
                }
            }
        }, "t1");

        t1.start();
        sleep(1);
        t1.interrupt();
        log.info("中断状态:{}", t1.isInterrupted());
    }
}

运行结果:
在这里插入图片描述

6.2 打断处于阻塞状态的线程

注意:如果打断的是处于阻塞状态的线程,这时候会抛出一个InterruptedException,然后清空中断状态。

public class InterruptDemo01 {
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            sleep(2);
        }, "t1");

        t1.start();
        sleep(1);
        t1.interrupt();
        log.debug("中断状态:{}", t1.isInterrupted());
    }
}

运行结果:可以看到中断状态被清空为false了。

在这里插入图片描述


三、不推荐的方法

还有一些不推荐使用的方法,这些方法已过时,容易破坏同步代码块,造成线程死锁

方法名static说明
stop()停止线程运行
suspend()挂起(暂停)线程运行
resume()恢复线程运行
  • 22
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

用心听。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值