等待唤醒机制

等待唤醒机制是Java中实现线程间协作的方式,涉及wait()和notify()操作。线程通过调用对象的wait()方法进入等待状态,释放锁,而其他线程可调用notify()或notifyAll()唤醒等待线程。示例代码展示了一个生产者-消费者问题的解决,强调了同步代码块的重要性以避免异常。
摘要由CSDN通过智能技术生成

等待唤醒机制(Wait-Notify)是一种线程间协作的机制,用于实现线程之间的通信和同步。它主要涉及两个操作:等待(wait)和唤醒(notify)。

等待唤醒机制通常应用于多线程环境下,其中一个线程等待某个条件得到满足,而另一个线程负责在满足条件时通知等待的线程继续执行。

具体来说,当一个线程调用对象的wait()方法时,它会释放当前持有的锁,并且进入等待状态,直到其他线程通过notify()或notifyAll()方法来唤醒它。被唤醒的线程将重新尝试获取锁,然后继续执行。

而唤醒线程通常在满足某个条件时,通过调用对象的notify()或notifyAll()方法来通知正在等待的线程继续执行。notify()方法会随机选择一个等待线程进行唤醒,而notifyAll()方法会唤醒所有等待的线程,使它们进入就绪状态,等待获取锁以继续执行。

等待唤醒机制提供了一种有效的线程间协作方式,使得线程可以根据特定条件进行等待和唤醒,从而实现对共享资源的更好利用和管理。

需要注意的是,等待唤醒机制必须在同步代码块中使用,即对共享对象进行操作,以确保正确的并发控制和线程间的协作。在调用wait()、notify()或notifyAll()方法之前,线程必须先获得相应对象的锁,否则会抛出IllegalMonitorStateException异常。

下面是一个简单的Java代码示例,演示了等待唤醒机制的实现:

public class WaitNotifyExample {
    public static void main(String[] args) {
        Message message = new Message();

        Thread producerThread = new Thread(new Producer(message));
        Thread consumerThread = new Thread(new Consumer(message));

        producerThread.start();
        consumerThread.start();
    }
}

class Message {
    private String content;
    private boolean isProduced;

    public synchronized void produce(String content) {
        while (isProduced) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        this.content = content;
        System.out.println("Produced: " + content);
        isProduced = true;
        notify();
    }

    public synchronized String consume() {
        while (!isProduced) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        String consumedContent = content;
        System.out.println("Consumed: " + consumedContent);
        isProduced = false;
        notify();

        return consumedContent;
    }
}

class Producer implements Runnable {
    private Message message;

    public Producer(Message message) {
        this.message = message;
    }

    @Override
    public void run() {
        String[] contents = {"Message 1", "Message 2", "Message 3"};

        for (String content : contents) {
            message.produce(content);

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Consumer implements Runnable {
    private Message message;

    public Consumer(Message message) {
        this.message = message;
    }

    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            String consumedContent = message.consume();

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

下面我们逐步解释代码的细节:

  1. 首先,我们创建了一个Message类,用于消息传递。该类包含了一个消息内容content和一个表示是否已经生产消息的标志isProduced

  2. Message类中的produce()方法用于生产消息。在该方法中,使用synchronized关键字确保多个线程在访问produce()方法时的互斥性。

  3. produce()方法中,使用while循环来检查是否已经生产消息。如果isProducedtrue,说明已经生产了消息,则调用wait()方法让当前线程进入等待状态,直到被其他线程调用notify()方法唤醒。

  4. 当前线程被唤醒后,会继续执行后续代码,将传入的消息内容赋值给content变量,并将isProduced标志设置为true,表示消息已经生产。然后通过notify()方法唤醒在等待的其他线程。

  5. Message类中的consume()方法用于消费消息。同样,使用synchronized关键字确保多个线程在访问consume()方法时的互斥性。

  6. consume()方法中,同样使用while循环来检查是否已经生产消息。如果isProducedfalse,说明还没有生产消息,则调用wait()方法让当前线程进入等待状态,直到被其他线程调用notify()方法唤醒。

  7. 当前线程被唤醒后,会继续执行后续代码,将content变量的值作为消费的消息内容,并将isProduced标志设置为false,表示消息已经被消费。然后通过notify()方法唤醒在等待的其他线程。

  8. 在主程序中,我们创建了一个Message对象和两个线程:生产者线程Producer和消费者线程Consumer

  9. 生产者线程通过调用message.produce(content)方法来生产消息。在示例中,我们定义了3个消息内容,分别进行生产,并且每次生产完后等待1秒钟。

  10. 消费者线程通过调用message.consume()方法来消费消息。在示例中,我们简单地循环3次消费消息,并且每次消费后等待1秒钟。

通过以上操作,生产者和消费者线程之间进行消息的生产和消费,并且使用了等待唤醒机制进行线程间的通信和同步。当消息已经生产时,生产者线程进入等待状态,等待消费者线程消费完毕后唤醒;当消息还没有被生产时,消费者线程进入等待状态,等待生产者线程生产完毕后唤醒。

需要注意的是,为了保证正确的并发控制和线程间的协作,必须在调用wait()notify()notifyAll()方法之前先获取锁(即使用synchronized关键字修饰的方法或代码块),否则会抛出IllegalMonitorStateException异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>