Semaphore implements producer and consumer issues, easy to understand
1. Analysis
There are two core issues that need to be paid attention to between producers and consumers:
- Producers cannot put
- Consumers cannot consume at the same time
Object abstraction
Consumers, producers, warehouses
2. Source code:
warehouse
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;
/**
* @author VernHe
*/
public class Buffer {
//同时进入核心区的人数
Semaphore mutex = new Semaphore(1);
//空位的数量
Semaphore notFull = new Semaphore(5);
//产品的数量
Semaphore notEmpty = new Semaphore(0);
//操作的仓库
private List<String> list = new ArrayList<>(5);
/**
* 放入产品
* @param str
* @throws InterruptedException
*/
public void write(String str) throws InterruptedException {
//仓库有空位时
notFull.acquire();
try {
//看有没有线程在核心区
mutex.acquire();
//放入产品
list.add(str);
} finally {
//退出核心区
mutex.release();
//增加一个不空的位置
notEmpty.release();
}
}
/**
* 取出产品
* @return
* @throws InterruptedException
*/
public String read() throws InterruptedException{
//有产品可以拿的时候
notEmpty.acquire();
try {
//进入核心区
mutex.acquire();
//拿产品
return list.remove(0);
} finally {
//退出核心区
mutex.release();
//空位增加
notFull.release();
}
}
}
Producer
/**
* 生产者,放入产品
* @author VernHe
*/
public class Producer implements Runnable{
private Buffer buffer;
public Producer(Buffer buffer) {
this.buffer = buffer;
}
public Buffer getBuffer() {
return buffer;
}
public void setBuffer(Buffer buffer) {
this.buffer = buffer;
}
public Producer() {
}
@Override
public void run() {
String char1="hello";
for (int i = 0; i < 5; i++) {
String str = String.valueOf(char1.charAt(i));
try {
buffer.write(str);
System.out.println(Thread.currentThread().getName() + "写入 <--- " + str);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
consumer
/**
* 消费者,消费产品
* @author VernHe
*/
public class Consumer implements Runnable{
private Buffer buffer;
public Consumer() {
}
public Consumer(Buffer buffer) {
this.buffer = buffer;
}
public Buffer getBuffer() {
return buffer;
}
public void setBuffer(Buffer buffer) {
this.buffer = buffer;
}
@Override
public void run() {
String c;
StringBuffer result = new StringBuffer();
for (int i = 0; i < 5; i++) {
// for (int i = 0; i < 5; i++) {
try {
c = buffer.read();
result.append(c);
System.out.println(Thread.currentThread().getName() + "读到 ---> " + c);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.printf("最终读取的结果为:" + result.toString());
}
}
test
/**
* @author VernHe
*/
public class Pv {
public static void main(String[] args) {
Buffer buffer = new Buffer();
Producer producer = new Producer(buffer);
Consumer consumer = new Consumer(buffer);
/**
* 一个生产者一个消费者
*/
Consumer consumer2 = new Consumer(buffer);
Thread t1 = new Thread(producer,"Producer_01");
Thread t2 = new Thread(consumer,"Consumer_01");
t1.start();
t2.start();
}
}
For multiple producers and multiple consumers, you only need to define a few more producer and consumer objects.