Как заставить потоки работать в порядке, используя CountDownlatch?
Я учусь, как использовать countdownLatch в Java, и я создал простой пример, как показано ниже в коде.
Что я узнал об этом механизме, так это то, что это просто способ заставить только ОДИН поток ждать других, пока они не закончат свою работу, а затем тот поток, который ожидал, запустит свою работу, когда другой (ие) поток (ы) завершат,
Мой вопрос заключается в том, что если у меня есть 4 потока 't1, t2, t3 и t4', и они должны начинаться в порядке, как указано, и каждый поток должен начинаться, когда завершается предыдущий / предыдущий. другими словами, t2 должен ждать t1 и начинать, когда заканчивается t1, и t3 должен ждать t2 и начинается, когда заканчивается t2, t4 должен ждать t3 и начинается, когда заканчивается t3.
1-как сделать это, используя CountDownLatch и циклический барьер?
2 - параметр countDown, передаваемый конструктору класса CountDownLatch, должен представлять число ожидающих потоков?
код:
public class MainClass {
public static void main(String[] args) {
CountDownLatch latch1 = new CountDownLatch(1);
Thread t1 = new Thread(new AscendingOrder(latch1));
Thread t2 = new Thread(new DescendingOrder(latch1));
t1.start();
t2.start();
}
static class AscendingOrder implements Runnable {
private CountDownLatch latch;
public AscendingOrder(CountDownLatch latch) {
// TODO Auto-generated constructor stub
this.latch = latch;
}
public void run() {
// TODO Auto-generated method stub
System.out.println("thread t1 started.");
for (int i = 0; i < 10; i++)
System.out.println(i);
this.latch.countDown();
}
}
static class DescendingOrder implements Runnable {
private CountDownLatch latch;
public DescendingOrder(CountDownLatch latch1) {
// TODO Auto-generated constructor stub
this.latch = latch1;
}
public void run() {
// TODO Auto-generated method stub
System.out.println("thread t2 started and waiting");
try {
this.latch.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 10; i > 0; i--)
System.out.println(i);
}
}
}
1 ответ
1-как сделать это, используя CountDownLatch и циклический барьер?
CyclicBarrier не идеально подходит для этой проблемы, я написал пост, сравнивающий два, пожалуйста, посмотрите здесь
public class CountDownLatchTest {
public static void main(String[] args) {
CountDownLatch first = new CountDownLatch(1);
CountDownLatch prev = first;
for(int i=0;i<10;i++) {
CountDownLatch next = new CountDownLatch(1);
new TestThread(prev, next, i).start();
prev = next;
}
first.countDown();
}
public static class TestThread extends Thread {
private CountDownLatch prev;
private CountDownLatch next;
private int id;
public TestThread(CountDownLatch prev, CountDownLatch next, int id) {
this.prev = prev;
this.next = next;
this.id = id;
}
public void run() {
if (prev != null) {
try {
prev.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
doWork();
} finally {
if (next != null) {
next.countDown();
}
}
}
public void doWork() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Work done in Thread : "
+ id);
}
}
}
2- параметр countDown, передаваемый конструктору класса CountDownLatch, должен представлять число ожидающих потоков?
CountDownLatch.await () будет ждать, пока метод CountDownLatch.countDown() не будет вызван для параметра countDown.