Я делаю приложение, которое состоит из двух потоков: один из них записывает значение в LinkedBlockingQueue, другой читает. Я использую ScheduledExecutorService для выполнения этой операции в некоторый период в секундах. Проблема в том, что мое приложение зависает при использовании метода BlockingQueue, и я не могу понять, почему.
Это общий ресурс:
class Res{
AtomicInteger atomicInteger = new AtomicInteger(0);
BlockingQueue<String> q = new LinkedBlockingQueue<>();
}
Это читатель
Semaphore semaphore = new Semaphore(1); /this is for reader does not take two places in thread pool
Runnable reader = ()->{
try {
semaphore.acquire();
System.out.println(res.q.take()+" "+res.atomicInteger.incrementAndGet());
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Writer:
Runnable writer = ()->{
res.q.add("hi");
};
Полный код:
class Res{
AtomicInteger atomicInteger = new AtomicInteger(0);
BlockingQueue<String> q = new LinkedBlockingQueue<>();
}
public class Main {
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);
Res res = new Res();
Semaphore semaphore = new Semaphore(1); //this is for reader does not take two places in thread pool
Runnable reader = ()->{
try {
semaphore.acquire();
System.out.println(res.q.take()+" "+res.atomicInteger.incrementAndGet());
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Runnable writer = ()->{
res.q.add("hi");
};
Random rnd = new Random();
for (int i = 0; i < 20; i++) {
int time = rnd.nextInt(5)+ 2;
executorService.schedule(writer,time, TimeUnit.SECONDS);
}
for (int i = 0; i < 20; i++) {
int time = rnd.nextInt(5)+ 2;
executorService.schedule(reader,time, TimeUnit.SECONDS);
}
executorService.shutdown();
}
Должно быть напечатано двадцать строк "hi [number]", но в какой-то строке оно застывает. Например, мой текущий отпечаток:
hi 1
hi 2
hi 3
hi 4
hi 5
Я узнал, если я увеличу количество потоков newScheduledThreadPool(20)
, он начинает работать, но как я могу сделать это с двумя потоками? Спасибо!