同步模式之顺序控制,如何控制三个线程依次输出: abc abc abc abc abc?
1.通过 synchronized wait notifyAll 控制三个线程 依次输出 abc abc abc abc abc
private static Thread t1, t2, t3;
// 用于控制当前哪一个线程执行, state = 0时 t1线程执行, state = 1时 t2线程执行,state = 2时 t3线程执行
private static int state = 0;
@Test
public void test3() throws InterruptedException {
t1 = new Thread(() -> {
synchronized (lock) {
for (int i = 0; i < 5; i++) {
while (state != 0) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
log.info("---------------" + i + "-------------------");
log.info("a");
state = 1;
lock.notifyAll();
}
}
});
t2 = new Thread(() -> {
synchronized (lock) {
for (int i = 0; i < 5; i++) {
while (state != 1) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
log.info("b");
state = 2;
lock.notifyAll();
}
}
});
t3 = new Thread(() -> {
synchronized (lock) {
for (int i = 0; i < 5; i++) {
while (state != 2) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
log.info("c");
state = 0;
lock.notifyAll();
}
}
});
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
}
2.通过 ReenTrantLock 控制三个线程 依次输出 abc abc abc abc abc
private static Thread t1, t2, t3;
// 用于控制当前哪一个线程执行, state = 0时 t1线程执行, state = 1时 t2线程执行,state = 2时 t3线程执行
private static int state = 0;
private static final Lock reentrantLock = new ReentrantLock();
private static final Condition[] conditions = new Condition[3];
@Test
public void test4() throws InterruptedException {
for (int i = 0; i < 3; i++) {
conditions[i] = reentrantLock.newCondition();
}
Thread t1 = new Thread(() -> {
reentrantLock.lock();
try {
for (int i = 0; i < 5; i++) {
while (state != 0) {
conditions[0].await();
}
log.info("---------------" + i + "-------------------");
log.info("a");
state = 1;
conditions[1].signal();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
reentrantLock.unlock();
}
});
Thread t2 = new Thread(() -> {
reentrantLock.lock();
try {
for (int i = 0; i < 5; i++) {
while (state != 1) {
conditions[1].await();
}
log.info("b");
state = 2;
conditions[2].signal();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
reentrantLock.unlock();
}
});
Thread t3 = new Thread(() -> {
reentrantLock.lock();
try {
for (int i = 0; i < 5; i++) {
while (state != 2) {
conditions[2].await();
}
log.info("c");
state = 0;
conditions[0].signal();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
reentrantLock.unlock();
}
});
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
}
3.通过 park unpark 控制三个线程 依次输出 abc abc abc abc abc
private static Thread t1, t2, t3;
@Test
public void test5() throws InterruptedException {
t1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
log.info("---------------" + i + "-------------------");
log.info("a");
LockSupport.unpark(t2);
LockSupport.park();
}
});
t2 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
LockSupport.park();
log.info("b");
LockSupport.unpark(t3);
}
});
t3 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
LockSupport.park();
log.info("c");
LockSupport.unpark(t1);
}
});
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
}