import java.util.Queue;
import java.util.LinkedList;
import java.util.Random;
class Main {
public static void main
(String[] args
) { // Разделяемые потоками ресурсы - буфер и монитор
final Queue<String> sharedBuffer = new LinkedList<>();
// Потоки, пока не запускаются
final Thread adder
= new Adder
(sharedBuffer, sharedMonitor
),
printer = new Printer(sharedBuffer, sharedMonitor);
// Если все написано верно, вне зависимости от порядка запуска потоки
// отрабатают без дедлоков
if (new Random().
nextBoolean()) { adder.start();
printer.start();
} else {
printer.start();
adder.start();
}
}
}
/* Producer */
private final Queue<String> buffer;
public Adder
(Queue
<String
> buffer,
Object monitor
) { this.buffer = buffer;
this.monitor = monitor;
}
@Override
public void run() {
for (int i = 0; i < 2; i++) {
// Захватываем монитор
synchronized (monitor) {
// Добавляем строки в буфер
buffer.add("foo " + i);
buffer.add("bar " + i);
// Будим поток-потребитель
monitor.notify();
// И засыпаем пока он не обработает строки в буфере
while (buffer.size() != 0) {
try {
monitor.wait();
ex.printStackTrace();
}
}
}
}
}
}
/* Consumer */
class Printer
extends Thread { private final Queue<String> buffer;
public Printer
(Queue
<String
> buffer,
Object monitor
) { this.buffer = buffer;
this.monitor = monitor;
}
@Override
public void run() {
for (int i = 0; i < 2; i++) {
// Захватываем монитор
synchronized (monitor) {
// Спим пока поток-производитель не положит в буфер строки
while (buffer.size() != 2) {
try {
monitor.wait();
ex.printStackTrace();
}
}
// Достаем строки из буфера и печатаем
System.
out.
println(buffer.
poll()); System.
out.
println(buffer.
poll()); // Будим поток-производитель
monitor.notify();
}
}
}
}
aW1wb3J0IGphdmEudXRpbC5RdWV1ZTsKaW1wb3J0IGphdmEudXRpbC5MaW5rZWRMaXN0OwppbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKIApjbGFzcyBNYWluIHsKCXB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKCQkvLyDQoNCw0LfQtNC10LvRj9C10LzRi9C1INC/0L7RgtC+0LrQsNC80Lgg0YDQtdGB0YPRgNGB0YsgLSDQsdGD0YTQtdGAINC4INC80L7QvdC40YLQvtGACgkJZmluYWwgUXVldWU8U3RyaW5nPiBzaGFyZWRCdWZmZXIgPSBuZXcgTGlua2VkTGlzdDw+KCk7CgkJZmluYWwgT2JqZWN0IHNoYXJlZE1vbml0b3IgPSBuZXcgT2JqZWN0KCk7CgkJCgkJLy8g0J/QvtGC0L7QutC4LCDQv9C+0LrQsCDQvdC1INC30LDQv9GD0YHQutCw0Y7RgtGB0Y8KCQlmaW5hbCBUaHJlYWQgYWRkZXIgPSBuZXcgQWRkZXIoc2hhcmVkQnVmZmVyLCBzaGFyZWRNb25pdG9yKSwKCQkJcHJpbnRlciA9IG5ldyBQcmludGVyKHNoYXJlZEJ1ZmZlciwgc2hhcmVkTW9uaXRvcik7CgkJCgkJLy8g0JXRgdC70Lgg0LLRgdC1INC90LDQv9C40YHQsNC90L4g0LLQtdGA0L3Qviwg0LLQvdC1INC30LDQstC40YHQuNC80L7RgdGC0Lgg0L7RgiDQv9C+0YDRj9C00LrQsCDQt9Cw0L/Rg9GB0LrQsCDQv9C+0YLQvtC60LggCgkJLy8g0L7RgtGA0LDQsdCw0YLQsNGO0YIg0LHQtdC3INC00LXQtNC70L7QutC+0LIKCQlpZiAobmV3IFJhbmRvbSgpLm5leHRCb29sZWFuKCkpIHsKCQkJYWRkZXIuc3RhcnQoKTsKCQkJcHJpbnRlci5zdGFydCgpOwoJCX0gZWxzZSB7CgkJCXByaW50ZXIuc3RhcnQoKTsKCQkJYWRkZXIuc3RhcnQoKTsKCQl9Cgl9Cn0KIAovKiBQcm9kdWNlciAqLwpjbGFzcyBBZGRlciBleHRlbmRzIFRocmVhZCB7Cglwcml2YXRlIGZpbmFsIFF1ZXVlPFN0cmluZz4gYnVmZmVyOwoJcHJpdmF0ZSBmaW5hbCBPYmplY3QgbW9uaXRvcjsKIAoJcHVibGljIEFkZGVyKFF1ZXVlPFN0cmluZz4gYnVmZmVyLCBPYmplY3QgbW9uaXRvcikgewoJCXRoaXMuYnVmZmVyID0gYnVmZmVyOwoJCXRoaXMubW9uaXRvciA9IG1vbml0b3I7Cgl9CiAKCUBPdmVycmlkZQoJcHVibGljIHZvaWQgcnVuKCkgewoJCWZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CgkJCS8vINCX0LDRhdCy0LDRgtGL0LLQsNC10Lwg0LzQvtC90LjRgtC+0YAKCQkJc3luY2hyb25pemVkIChtb25pdG9yKSB7CgkJCQkvLyDQlNC+0LHQsNCy0LvRj9C10Lwg0YHRgtGA0L7QutC4INCyINCx0YPRhNC10YAKCQkJCWJ1ZmZlci5hZGQoImZvbyAiICsgaSk7CgkJCQlidWZmZXIuYWRkKCJiYXIgIiArIGkpOwoJCQkJLy8g0JHRg9C00LjQvCDQv9C+0YLQvtC6LdC/0L7RgtGA0LXQsdC40YLQtdC70YwKCQkJCW1vbml0b3Iubm90aWZ5KCk7CgkJCQkvLyDQmCDQt9Cw0YHRi9C/0LDQtdC8INC/0L7QutCwINC+0L0g0L3QtSDQvtCx0YDQsNCx0L7RgtCw0LXRgiDRgdGC0YDQvtC60Lgg0LIg0LHRg9GE0LXRgNC1CgkJCQl3aGlsZSAoYnVmZmVyLnNpemUoKSAhPSAwKSB7CgkJCQkJdHJ5IHsKCQkJCQkJbW9uaXRvci53YWl0KCk7CgkJCQkJfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKCQkJCQkJZXgucHJpbnRTdGFja1RyYWNlKCk7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoJfQp9CiAKLyogQ29uc3VtZXIgKi8KY2xhc3MgUHJpbnRlciBleHRlbmRzIFRocmVhZCB7Cglwcml2YXRlIGZpbmFsIFF1ZXVlPFN0cmluZz4gYnVmZmVyOwoJcHJpdmF0ZSBmaW5hbCBPYmplY3QgbW9uaXRvcjsKIAoJcHVibGljIFByaW50ZXIoUXVldWU8U3RyaW5nPiBidWZmZXIsIE9iamVjdCBtb25pdG9yKSB7CgkJdGhpcy5idWZmZXIgPSBidWZmZXI7CgkJdGhpcy5tb25pdG9yID0gbW9uaXRvcjsKCX0KIAoJQE92ZXJyaWRlCglwdWJsaWMgdm9pZCBydW4oKSB7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCAyOyBpKyspIHsKCQkJLy8g0JfQsNGF0LLQsNGC0YvQstCw0LXQvCDQvNC+0L3QuNGC0L7RgAoJCQlzeW5jaHJvbml6ZWQgKG1vbml0b3IpIHsKCQkJCS8vINCh0L/QuNC8INC/0L7QutCwINC/0L7RgtC+0Lot0L/RgNC+0LjQt9Cy0L7QtNC40YLQtdC70Ywg0L3QtSDQv9C+0LvQvtC20LjRgiDQsiDQsdGD0YTQtdGAINGB0YLRgNC+0LrQuAoJCQkJd2hpbGUgKGJ1ZmZlci5zaXplKCkgIT0gMikgewoJCQkJCXRyeSB7CgkJCQkJCW1vbml0b3Iud2FpdCgpOwoJCQkJCX0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CgkJCQkJCWV4LnByaW50U3RhY2tUcmFjZSgpOwoJCQkJCX0KCQkJCX0KCQkJCS8vINCU0L7RgdGC0LDQtdC8INGB0YLRgNC+0LrQuCDQuNC3INCx0YPRhNC10YDQsCDQuCDQv9C10YfQsNGC0LDQtdC8CgkJCQlTeXN0ZW0ub3V0LnByaW50bG4oYnVmZmVyLnBvbGwoKSk7CgkJCQlTeXN0ZW0ub3V0LnByaW50bG4oYnVmZmVyLnBvbGwoKSk7CgkJCQkvLyDQkdGD0LTQuNC8INC/0L7RgtC+0Lot0L/RgNC+0LjQt9Cy0L7QtNC40YLQtdC70YwKCQkJCW1vbml0b3Iubm90aWZ5KCk7CgkJCX0KCQl9Cgl9Cn0=