使用wait()和notify()方法和BlockingQueue两种方法编写Java程序:一个线程向一个4位循环缓冲区中循环写入1-10的随机数,另一个线程将循环缓冲区中数据取出打印出来。的解题思路,比如总共设计几个类,各个类的用途、成员、主要方法等及其之间调用关系等
时间: 2024-02-20 15:57:19 浏览: 83
这个问题需要设计三个类:一个是生产者类,一个是消费者类,还有一个是循环缓冲区类。
1. 循环缓冲区类
该类包含一个长度为4的int数组,用来存储生产者产生的数据。还包含两个指针head和tail,分别指向数组的头和尾。提供如下方法:
- void put(int value):将数据放入缓冲区中
- int get():从缓冲区中取出数据
- boolean isEmpty():判断缓冲区是否为空
- boolean isFull():判断缓冲区是否已满
2. 生产者类
该类实现Runnable接口,用于在一个单独的线程中循环产生1-10的随机数,然后将其放入循环缓冲区中。提供如下方法:
- void run():循环产生1-10的随机数,并将其放入循环缓冲区中
3. 消费者类
该类实现Runnable接口,用于在一个单独的线程中从循环缓冲区中取出数据,并打印出来。提供如下方法:
- void run():循环从循环缓冲区中取出数据,并打印出来
在主函数中,创建一个循环缓冲区对象和生产者对象、消费者对象,然后启动两个线程,分别执行生产者对象和消费者对象的run方法。
使用wait()和notify()方法实现的话,可以在循环缓冲区类中添加如下方法:
- void put(int value):将数据放入缓冲区中,并在缓冲区已满时调用wait()方法等待
- int get():从缓冲区中取出数据,并在缓冲区为空时调用wait()方法等待
- void notifyPut():在放入数据后调用notify()方法唤醒等待在缓冲区已满上的线程
- void notifyGet():在取出数据后调用notify()方法唤醒等待在缓冲区为空上的线程
具体实现方式可以参考如下代码:
```java
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class Main {
public static void main(String[] args) {
BlockingQueue<Integer> buffer = new LinkedBlockingQueue<>(4);
Producer producer = new Producer(buffer);
Consumer consumer = new Consumer(buffer);
new Thread(producer).start();
new Thread(consumer).start();
}
}
class Producer implements Runnable {
private BlockingQueue<Integer> buffer;
private Random random;
public Producer(BlockingQueue<Integer> buffer) {
this.buffer = buffer;
this.random = new Random();
}
@Override
public void run() {
while (true) {
try {
int value = random.nextInt(10) + 1;
buffer.put(value);
System.out.println("Produced " + value);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable {
private BlockingQueue<Integer> buffer;
public Consumer(BlockingQueue<Integer> buffer) {
this.buffer = buffer;
}
@Override
public void run() {
while (true) {
try {
int value = buffer.take();
System.out.println("Consumed " + value);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
```
在这段代码中,我们使用了Java提供的线程安全的阻塞队列BlockingQueue来实现循环缓冲区的功能,从而避免了使用wait()和notify()方法可能会带来的线程安全问题。生产者线程通过调用BlockingQueue的put方法将数据放入队列中,如果队列已满则会阻塞等待直到有消费者线程取出数据。消费者线程通过调用BlockingQueue的take方法从队列中取出数据,如果队列为空则会阻塞等待直到有生产者线程放入数据。
阅读全文