线程间通信

线程是操作系统调度的最小单位,有自己的栈空间,可以按照既定
的代码逐步执行,但是如果每个线程间都孤立地运行,就会造资源浪
费。
所以在现实中,如果需要多个线程按照指定的规则共同完成一个任
务,那么这些线程之间就需要互相协调,这个过程被称为线程的通信。
线程的通信可以被定义为:当多个线程共同操作共享的资源时,线
程间通过某种方式互相告知自己的状态,以避免无效的资源争夺。
线程间通信的方式可以有很多种:等待-通知、共享内存、管道
流。每种方式用不同的方法来实现,这里首先介绍等待-通知的通信方
式。
等待-通知通信方式是Java中使用普遍的线程间通信方式,其经典
的案例是生产者-消费者模式
Java语言中等待-通知方式的线程间通信使用对象的wait()
notify()两类方法来实现。每个Java对象都有wait()notify()两类实例方
法,并且wait()notify()方法和对象的监视器是紧密相关的。

Java中的waitnotify方法是线程间通信和同步的核心机制,它们位于java.lang.Object类中,允许线程在特定条件下挂起和恢复执行。以下是这两个方法的原理及使用例子:

wait方法

  • 当一个线程调用对象的wait()方法时,它会释放该对象的监视器锁(也称为对象锁或 intrinsic lock),并进入等待(阻塞)状态。
  • 调用wait()方法必须在同步代码块(即synchronized修饰的代码块或方法)内进行,否则会抛出IllegalMonitorStateException异常。
  • 线程调用wait()时,会一直等待,直到其他线程调用同一个对象上的notify()notifyAll()方法,或者超过指定的等待时间(如果有传递超时参数给wait(long timeout))。

例如:

class SharedResource {
    private boolean dataAvailable = false;

    public synchronized void produce() {
        while (dataAvailable) { // 数据已满,生产者线程等待
            try {
                wait();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt(); // 处理中断
            }
        }

        // 生产数据...
        dataAvailable = true;

        // 唤醒等待的消费者线程
        notify();
    }

    public synchronized void consume() {
        while (!dataAvailable) { // 数据为空,消费者线程等待
            try {
                wait();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }

        // 消费数据...
        dataAvailable = false;

        // 唤醒等待的生产者线程
        notify();
    }
}

在这个例子中,有两个线程分别扮演生产者和消费者的角色,共享一个资源。生产者在资源已满时调用wait(),释放锁并等待;消费者在资源空时同样调用wait()。当资源状态改变时,相应线程通过调用notify()来唤醒对方。

notify方法

  • notify()方法用于唤醒正在等待(因为调用了wait())同一对象监视器锁的一个线程。
  • 它并不能确切指定唤醒哪个线程,而是从等待集合中随机选择一个线程,将其移出等待队列并放入可运行队列,然后该线程有机会获取锁并继续执行。

如果需要唤醒所有等待的线程,则应使用notifyAll()方法,它会唤醒所有等待在该对象上的线程。

注意:

  • 使用wait()notify()时必须正确处理异常,并且通常建议在循环中检查条件,因为即使线程被唤醒,条件可能仍未满足。
  • 这些方法基于“先入先出”(FIFO)原则,但不保证绝对的公平性,且在JDK的不同版本中其行为可能会有所变化。
  • 在现代Java编程中,推荐使用更高级别的同步框架如java.util.concurrent包下的工具类(如Semaphore、CountDownLatch、BlockingQueue等)来替代直接使用wait()notify(),这些工具类通常提供了更好的可读性和更强的线程同步控制能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

semicolon_helloword

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

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

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

打赏作者

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

抵扣说明:

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

余额充值