并发安全笔记6——线程通信

本文详细介绍了Java中线程间通信的wait、notify和join方法,这些方法用于在多线程环境中协调对共享资源的访问。wait使线程进入等待状态,释放锁;notify唤醒等待队列中的一个线程;join则使得当前线程等待另一个线程完成。所有这些操作都需在同步代码块中执行,确保线程安全。理解这些机制对于编写高效的并发程序至关重要。

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

线程之间可以通过写作方式完成一个任务,这就需要线程之间互相通信。当多个线程操作同一共享资源的时候,需要彼此通信告知状态避免资源争夺。

线程通信方式有

  • 共享内存:volatile 通过volatile让线程之间对共享资源的修改可见
  • 消息传递:wait/notify/join 线程之间可以通过消息来进行彼此通信
  • 管道流:管道输入/输出流的形式

主要了解消息传递,也就是wait/notify/join

wait/notify是一对都不陌生的线程通信方法,存在于Object类中

public class Object {

    private static native void registerNatives();
    static {
        registerNatives();
    }

    public final native Class<?> getClass();

    public native int hashCode();

    public boolean equals(Object obj) {
        return (this == obj);
    }


    protected native Object clone() throws CloneNotSupportedException;

    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

    public final native void notify();

    public final native void notifyAll();

    public final native void wait(long timeout) throws InterruptedException;

    public final void wait(long timeout, int nanos) throws InterruptedException {
        if (timeout < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos > 0) {
            timeout++;
        }

        wait(timeout);
    }

    public final void wait() throws InterruptedException {
        wait(0);
    }

    protected void finalize() throws Throwable { }
}

wait()、wait(long timeout, int nanos) 、notify()、notifyAll()本质都是调用了本地方法来完成的。

每个对象都有一个监视器锁,而平时说的获得锁就是获取到对象的监视器。通过对同一对象进行wait和notify本质上就是获取监视器锁后在释放并唤醒其他线程来抢占监视器锁。

wait和notify一定要在同步代码块中执行,因为线程之间的竞争是不确定性的,只有放在同步代码块中才能保证锁被获取到。wait一定要在notify之前执行,因为notify先于wait执行会导致notify唤醒失败。

wait执行后会立刻释放锁,以便其他线程可以执行notify,但是notify不会立刻释放锁,必须等到notify所在的线程执行完成才会释放锁。

调用wait方法后该线程就被放入等待队列中,notify执行之后会将等待队列中的线程放入同步队列中,进行锁的抢占。

join表示当前线程需要等待join的线程执行完成之后再继续执行。

从源码中可以看到,join方法内部实际上是调用了wait方法实现的等待。那么使用了wait之后并没有notify的动作,线程又如何重新执行的呢?

实际上线程再jvm层面实现run方法后会在jvm层面调用notify方法唤醒当前线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值