У меня проблема с пониманием Locks and Conditions на Java, я не понимаю, почему мой код попадает в тупик.
Моя программа состоит из Mainthread и Subthread, subthread является членом Mainthread. Оба потока выполняются в бесконечном цикле, цикл Subthread должен выполнять ровно одну итерацию, как только он получает сигнал для startCond из Mainthread. Mainthread должен дождаться окончания сигнала finishCond.Синхронизация нитей с замками
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
public static void main(String[] args) {
LockTest lt = new LockTest();
Mainthread m1 = lt.new Mainthread();
m1.start();
}
public class Mainthread extends Thread {
private Subthread sub = new Subthread();
public void run(){
System.out.println("Main start");
sub.start();
while(!isInterrupted()) {
try {
sub.getStartLock().lock();
sub.getStartCond().signal();
sub.getStartLock().unlock();
sub.getFinishLock().lock();
sub.getFinishCond().await();
sub.getFinishLock().unlock();
System.out.println("Main done");
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Subthread extends Thread {
private Lock startLock = new ReentrantLock();
private Lock finishLock = new ReentrantLock();
private Condition startCond = startLock.newCondition();
private Condition finishCond = finishLock.newCondition();
public Lock getStartLock() {
return startLock;
}
public Lock getFinishLock() {
return finishLock;
}
public Condition getStartCond() {
return startCond;
}
public Condition getFinishCond() {
return finishCond;
}
public void run() {
System.out.println("Sub start");
while(!isInterrupted()) {
try {
startLock.lock();
startCond.await();
startLock.unlock();
finishLock.lock();
finishCond.signal();
finishLock.unlock();
System.out.println("Sub done");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Мой ожидаемый результат будет:
Main сделано
Sub сделано
(повторяется столько раз, сколько это было выполнено в петлях).
Есть ли способ решить эту проблему проще?
Спасибо, просто Thread.yield() решил это. Я сделаю это принятым ответом. – derdoe
выход НЕ РЕШАЕТ, он только увеличивает шансы, что он будет работать. Доходность - это лишь намек на планировщик потоков. Его можно игнорировать. Более того, другой поток может начинаться до подпотока, а затем Main может продолжаться до того, как будет запущен sub. – Zielu
также я не знаю, где вы вкладываете свой доход, но любая итерация вашего цикла воссоздает проблему. После ожидания сигнал может быть отправлен до того, как другой поток начнет его ожидание. – Zielu