Не работает Condition в ReentrantLock
Основной класс:
public class TestMultithreading{
static private final Lock lock = new ReentrantLock();
static private final Condition cond1 = lock.newCondition();
static private final Condition cond2 = lock.newCondition();
static final ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(1);
public static void main(String[] args) throws InterruptedException{
ErrorHandler eh = new TestMultithreading().new ErrorHandler();
Thread t1 = new Thread(new Customer(lock, cond1));
Thread t2 = new Thread(new Customer(lock, cond1));
Thread t3 = new Thread(new Thrower(lock, cond2));
t1.start();
t2.start();
pool.schedule(t3, 1000, TimeUnit.MILLISECONDS); // Запускаю 3-ю катушку с откатом в 1с ибо как она срабатывает единажды, то чтоб сработала в время, когда уже на потоке Customer будет await()
}
}
Дальше у нас есть 2 класса, которые реализовуют Runnable.
Первый Customer класс имеет 2 экземпляра, которые будут соревноваться за действия в методе run().
Тот, который шустрее, первым заблокирует метод с помощью ReentrantLock. Но в определенный момент в нем вызовется метод await через условие, что методу надо перескочить с count == 3.
public class Customer extends Methods implements Runnable{
Lock lock;
Condition cond;
Customer(Lock lock, Condition cond){
this.lock = lock;
this.cond = cond;
}
@Override
public void run() {
lock.lock();
try {
while (count <= 10) {
while (count == 3) {
cond.await();
}
System.out.println(count);
increment();
cond.signalAll();
}
} catch (InterruptedException ex) {
Logger.getLogger(Customer.class.getName()).log(Level.SEVERE, null, ex);
} finally {
lock.unlock();
}
}
}
Спустя 1 минуту запускается поток Thrower, который должен помочь перескочить c count == 3 на count == 4. И с помощью signallAll() оповестить зависший ранее процесс.
public class Thrower extends Methods implements Runnable{
Lock lock;
Condition cond;
Thrower(Lock lock, Condition cond){
this.lock = lock;
this.cond = cond;
}
@Override
public void run() {
lock.lock();
try {
System.out.println("count" + count);
errorCase();
System.out.println("after count" + count);
cond.signalAll();
cond.await();
} catch (InterruptedException ex) {
Logger.getLogger(Thrower.class.getName()).log(Level.SEVERE, null, ex);
} finally {
lock.unlock();
}
}
}
Класс с методами и переменной, которые испозуют потоки:
class Methods{
static int count = 0;
void increment(){
count++;
}
void errorCase(){
count++;
}
}
В результате Customer засыпает, но не просыпается, даже после того как count == 4.
В чем же проблема?
0
1
2
count3
after count4
BUILD STOPPED (total time: 6 seconds)//программа остановленная вручную