多线程顺序执行之Lock-Condition
package dong;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j
public class LockTest {
public static final AtomicInteger cnt = new AtomicInteger(-1);
public static Lock lock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 10; i++) {
TimeUnit.SECONDS.sleep(2);
run();
System.out.println("--------------\n\n");
}
}
private static void run() throws InterruptedException {
final Condition condition2 = lock.newCondition();
log.info("condition2 hash={}", condition2.hashCode());
final Job job2 = new Job(2, condition2, null);
final Condition condition1 = lock.newCondition();
log.info("condition1 hash={}", condition1.hashCode());
final Job job1 = new Job(1, condition1, condition2);
final Condition condition0 = lock.newCondition();
log.info("condition0 hash={}", condition0.hashCode());
final Job job0 = new Job(0, condition0, condition1);
job2.setNextCondition(condition0);
job0.start();
TimeUnit.MILLISECONDS.sleep(200);
job1.start();
job2.start();
}
@Data
@Slf4j
static class Job extends Thread {
public Job(int index, Condition condition, Condition nextCondition) {
super("job" + index);
this.index = index;
this.condition = condition;
this.nextCondition = nextCondition;
}
private int index;
private Condition condition;
private Condition nextCondition;
private static final int cnt = 3;
@Override
public void run() {
for (int i = 0; i < cnt; i++) {
try {
lock.lock();
System.out.printf("%s %d condition=%d nextCondition0=%d \n", this.getName(), i, condition.hashCode(), nextCondition.hashCode());
final int now = LockTest.cnt.addAndGet(1);
Assert.assertEquals(index, now % 3);
TimeUnit.MILLISECONDS.sleep(100);
nextCondition.signal();
condition.await();
} catch (Exception e) {
log.info("notify job{}", index);
} finally {
lock.unlock();
}
}
log.info("finish one job{}", index);
lock.lock();
nextCondition.signal();
lock.unlock();
}
}
}