fork download
  1. import java.util.Queue;
  2. import java.util.LinkedList;
  3. import java.util.Random;
  4.  
  5. class Main {
  6. public static void main(String[] args) {
  7. // Разделяемые потоками ресурсы - буфер и монитор
  8. final Queue<String> sharedBuffer = new LinkedList<>();
  9. final Object sharedMonitor = new Object();
  10.  
  11. // Потоки, пока не запускаются
  12. final Thread adder = new Adder(sharedBuffer, sharedMonitor),
  13. printer = new Printer(sharedBuffer, sharedMonitor);
  14.  
  15. // Если все написано верно, вне зависимости от порядка запуска потоки
  16. // отрабатают без дедлоков
  17. if (new Random().nextBoolean()) {
  18. adder.start();
  19. printer.start();
  20. } else {
  21. printer.start();
  22. adder.start();
  23. }
  24. }
  25. }
  26.  
  27. /* Producer */
  28. class Adder extends Thread {
  29. private final Queue<String> buffer;
  30. private final Object monitor;
  31.  
  32. public Adder(Queue<String> buffer, Object monitor) {
  33. this.buffer = buffer;
  34. this.monitor = monitor;
  35. }
  36.  
  37. @Override
  38. public void run() {
  39. for (int i = 0; i < 2; i++) {
  40. // Захватываем монитор
  41. synchronized (monitor) {
  42. // Добавляем строки в буфер
  43. buffer.add("foo " + i);
  44. buffer.add("bar " + i);
  45. // Будим поток-потребитель
  46. monitor.notify();
  47. // И засыпаем пока он не обработает строки в буфере
  48. while (buffer.size() != 0) {
  49. try {
  50. monitor.wait();
  51. } catch (InterruptedException ex) {
  52. ex.printStackTrace();
  53. }
  54. }
  55. }
  56. }
  57. }
  58. }
  59.  
  60. /* Consumer */
  61. class Printer extends Thread {
  62. private final Queue<String> buffer;
  63. private final Object monitor;
  64.  
  65. public Printer(Queue<String> buffer, Object monitor) {
  66. this.buffer = buffer;
  67. this.monitor = monitor;
  68. }
  69.  
  70. @Override
  71. public void run() {
  72. for (int i = 0; i < 2; i++) {
  73. // Захватываем монитор
  74. synchronized (monitor) {
  75. // Спим пока поток-производитель не положит в буфер строки
  76. while (buffer.size() != 2) {
  77. try {
  78. monitor.wait();
  79. } catch (InterruptedException ex) {
  80. ex.printStackTrace();
  81. }
  82. }
  83. // Достаем строки из буфера и печатаем
  84. System.out.println(buffer.poll());
  85. System.out.println(buffer.poll());
  86. // Будим поток-производитель
  87. monitor.notify();
  88. }
  89. }
  90. }
  91. }
Success #stdin #stdout 0.04s 711168KB
stdin
Standard input is empty
stdout
foo 0
bar 0
foo 1
bar 1