有一个苹果箱,有10个人向这个箱子中每次随机放入一个苹果,有10个人每次随机从这个箱子中随机拿走一个苹果,同时需要满足箱子中的苹果总数不能超过50个。请用代码实现上面的场景
synchronized + wait-notify
public class AppleBox {
private int appleCount;
public synchronized void putApple() {
while (appleCount == 50) {
try {
//会释放锁
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
appleCount++;
String name = Thread.currentThread().getName();
System.out.println("[" + name + "]放入一个,当前盒子中苹果数:" + appleCount);
this.notifyAll();
}
public synchronized void takeApple() {
while (appleCount == 0) {
try {
//会释放锁
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
appleCount--;
String name = Thread.currentThread().getName();
System.out.println("[" + name + "]拿走一个,当前盒子中苹果数:" + appleCount);
this.notifyAll();
}
private static class AppleTaker implements Runnable {
private AppleBox appleBox;
public AppleTaker(AppleBox appleBox) {
this.appleBox = appleBox;
}
@Override
public void run() {
while (true) {
appleBox.takeApple();
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private static class ApplePutter implements Runnable {
private AppleBox appleBox;
public ApplePutter(AppleBox appleBox) {
this.appleBox = appleBox;
}
@Override
public void run() {
while (true) {
appleBox.putApple();
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
AppleBox appleBox = new AppleBox();
for (int i = 0; i < 20; i++) {
Thread t = new Thread(new ApplePutter(appleBox));
t.setName("ApplePutter:" + i);
t.start();
}
for (int i = 0; i < 20; i++) {
Thread t = new Thread(new AppleTaker(appleBox));
t.setName("AppleTaker:" + i);
t.start();
}
}
}
lock+condition【1】
public class AppleBox {
private int appleCount;
private final ReentrantLock lock = new ReentrantLock();
private final Condition producer = lock.newCondition();
private final Condition consumer = lock.newCondition();
public void putApple() {
lock.lock();
try {
//满了则生产者进入阻塞
while (appleCount == 50) {
try {
producer.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//未满则生产,生产之后通知消费
appleCount++;
String name = Thread.currentThread().getName();
System.out.println("[" + name + "]放入一个,当前盒子中苹果数:" + appleCount);
consumer.signalAll();
} finally {
lock.unlock();
}
}
public void takeApple() {
lock.lock();
try {
//空了则消费者阻塞
while (appleCount == 0) {
try {
consumer.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//不空,则消费一个,接着通知生产者生产
appleCount--;
String name = Thread.currentThread().getName();
System.out.println("[" + name + "]拿走一个,当前盒子中苹果数:" + appleCount);
producer.signalAll();
} finally {
lock.unlock();
}
}
private static class AppleTaker implements Runnable {
private AppleBox appleBox;
public AppleTaker(AppleBox appleBox) {
this.appleBox = appleBox;
}
@Override
public void run() {
while (true) {
appleBox.takeApple();
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private static class ApplePutter implements Runnable {
private AppleBox appleBox;
public ApplePutter(AppleBox appleBox) {
this.appleBox = appleBox;
}
@Override
public void run() {
while (true) {
appleBox.putApple();
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
AppleBox appleBox = new AppleBox();
for (int i = 0; i < 20; i++) {
Thread t = new Thread(new ApplePutter(appleBox));
t.setName("ApplePutter:" + i);
t.start();
}
for (int i = 0; i < 20; i++) {
Thread t = new Thread(new AppleTaker(appleBox));
t.setName("AppleTaker:" + i);
t.start();
}
}
}
lock+condition【2】
@Slf4j(topic = "guizy.ReentrantTest")
public class ReentrantTest {
private static final ReentrantLock lock = new ReentrantLock();
static Condition producer = lock.newCondition();
static Condition consumer = lock.newCondition();
static List<Integer> list = new ArrayList<>();
public static void main(String[] args) {
new Thread(() -> {
while (true) {
Sleeper.sleep(1);
lock.lock();
try {
while (list.isEmpty()) {
try {
consumer.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.remove(0);
log.info("消费一个");
producer.signal();
} finally {
lock.unlock();
}
}
}, "消费者").start();
Sleeper.sleep(1);
new Thread(() -> {
while (true) {
lock.lock();
try {
while (list.size() == 5) {
try {
producer.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.add(1);
log.info("生产一个");
consumer.signal();
} finally {
lock.unlock();
}
}
}, "生产者").start();
}
}
阻塞队列
public class Main {
public static void main(String[] args) {
LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
new Thread(() -> {
while (true) {
try {
//如果空了则take阻塞
Integer integer = queue.take();
System.out.println(Thread.currentThread().getName() + " " + integer);
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "消费者").start();
for (int i = 0; i < 5; i++) {
new Thread(() -> {
while (true) {
try {
//如果满了则put阻塞
queue.put(new Random().nextInt(100));
System.out.println(Thread.currentThread().getName());
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "生产者" + (i + 1)).start();
}
}
}