86 lines
2.2 KiB
Java
86 lines
2.2 KiB
Java
|
import java.util.concurrent.locks.*;
|
||
|
|
||
|
class FullException extends Exception {
|
||
|
FullException(String msg) { super(msg); }
|
||
|
}
|
||
|
|
||
|
class Box<T> {
|
||
|
private T[] items = (T[]) new Object[3];
|
||
|
private int count = 0;
|
||
|
private Lock lock = new ReentrantLock();
|
||
|
private Condition notFull = lock.newCondition(), notEmpty = lock.newCondition();
|
||
|
|
||
|
void add(T item) throws FullException, InterruptedException {
|
||
|
lock.lock();
|
||
|
try {
|
||
|
if (count == items.length) throw new FullException("Box is full");
|
||
|
while (count == items.length) notFull.await();
|
||
|
items[count++] = item;
|
||
|
notEmpty.signal();
|
||
|
} finally {
|
||
|
lock.unlock();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
T retrieve() throws InterruptedException {
|
||
|
lock.lock();
|
||
|
try {
|
||
|
while (count == 0) notEmpty.await();
|
||
|
T item = items[--count];
|
||
|
notFull.signal();
|
||
|
return item;
|
||
|
} finally {
|
||
|
lock.unlock();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
boolean isEmpty() {
|
||
|
return count == 0;
|
||
|
}
|
||
|
|
||
|
void clear() {
|
||
|
count = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class Student {
|
||
|
String name;
|
||
|
Student(String name) { this.name = name; }
|
||
|
public String toString() { return name; }
|
||
|
}
|
||
|
|
||
|
public class Main {
|
||
|
public static void main(String[] args) throws Exception {
|
||
|
Box<Integer> intBox = new Box<>();
|
||
|
Box<String> strBox = new Box<>();
|
||
|
Box<Student> studentBox = new Box<>();
|
||
|
|
||
|
Thread t1 = new Thread(() -> {
|
||
|
try {
|
||
|
intBox.add(1);
|
||
|
intBox.add(2);
|
||
|
intBox.add(3);
|
||
|
System.out.println(intBox.retrieve());
|
||
|
} catch (Exception e) { e.printStackTrace(); }
|
||
|
});
|
||
|
|
||
|
Thread t2 = new Thread(() -> {
|
||
|
try {
|
||
|
strBox.add("Hello");
|
||
|
System.out.println(strBox.retrieve());
|
||
|
} catch (Exception e) { e.printStackTrace(); }
|
||
|
});
|
||
|
|
||
|
Thread t3 = new Thread(() -> {
|
||
|
try {
|
||
|
studentBox.add(new Student("Alice"));
|
||
|
System.out.println(studentBox.retrieve());
|
||
|
} catch (Exception e) { e.printStackTrace(); }
|
||
|
});
|
||
|
|
||
|
t1.start();
|
||
|
t2.start();
|
||
|
t3.start();
|
||
|
}
|
||
|
}
|