以下是一个不使用线程安全类的生产者-消费者问题的解决方法的代码示例:
import java.util.ArrayList;
import java.util.List;
class Producer implements Runnable {
private List buffer;
private final int bufferSize;
private int value = 0;
public Producer(List buffer, int bufferSize) {
this.buffer = buffer;
this.bufferSize = bufferSize;
}
@Override
public void run() {
while (true) {
synchronized (buffer) {
try {
// 如果缓冲区已满,等待消费者消费
while (buffer.size() == bufferSize) {
buffer.wait();
}
// 生产一个数据并放入缓冲区
buffer.add(value);
System.out.println("Produced: " + value);
value++;
// 通知消费者可以消费数据了
buffer.notifyAll();
// 模拟生产过程耗时
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
class Consumer implements Runnable {
private List buffer;
public Consumer(List buffer) {
this.buffer = buffer;
}
@Override
public void run() {
while (true) {
synchronized (buffer) {
try {
// 如果缓冲区为空,等待生产者生产
while (buffer.isEmpty()) {
buffer.wait();
}
// 从缓冲区取出一个数据并消费
int value = buffer.remove(0);
System.out.println("Consumed: " + value);
// 通知生产者可以继续生产数据
buffer.notifyAll();
// 模拟消费过程耗时
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class Main {
public static void main(String[] args) {
List buffer = new ArrayList<>();
int bufferSize = 5;
// 创建一个生产者线程和一个消费者线程
Thread producerThread = new Thread(new Producer(buffer, bufferSize));
Thread consumerThread = new Thread(new Consumer(buffer));
// 启动生产者和消费者线程
producerThread.start();
consumerThread.start();
}
}
在这个示例中,生产者线程通过synchronized
关键字来保护共享缓冲区,确保在访问缓冲区时只有一个线程能够执行。当缓冲区已满时,生产者线程调用wait()
方法进入等待状态,直到消费者线程消费了数据后通知它继续生产。消费者线程也通过synchronized
关键字来保护共享缓冲区,当缓冲区为空时,消费者线程调用wait()
方法进入等待状态,直到生产者线程生产了数据后通知它继续消费。
这种方法虽然能够解决生产者-消费者问题,但需要手动使用synchronized
关键字来保护共享资源,增加了编码的复杂性,并且容易出错。相比之下,使用线程安全类(如AtomicInteger
和SynchronizedList
)能够更方便地实现线程安全,并且减少了手动编写同步代码的工作量。