用volatile的可见性或者用重入锁+Condition来控制先后顺序
官方题解的原子类我还没学QAQ
第一种方法的优势在于无锁,缺点在于不满足顺序性的时候还是会进行顺序性是否符合的询问。
第二种方法优势在于,不满足顺序性的时候会让线程等待,缺点在于需要上锁和解锁。
方法1:volatile
class Foo {
private volatile boolean isFirstFinished = false;
private volatile boolean isSecondFinished = false;
public Foo() {
}
public void first(Runnable printFirst) throws InterruptedException {
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
isFirstFinished = true;
}
public void second(Runnable printSecond) throws InterruptedException {
while(isFirstFinished == false)
{Thread.yield();}
// printSecond.run() outputs "second". Do not change or remove this line.
printSecond.run();
isSecondFinished = true;
}
public void third(Runnable printThird) throws InterruptedException {
while(isSecondFinished == false)
{Thread.yield();}
// printThird.run() outputs "third". Do not change or remove this line.
printThird.run();
}
}
方法2:重入锁+Condition
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Foo {
int num = 1;
Lock lock;
//精确的通知和唤醒线程
Condition condition2, condition3;
public Foo() {
lock = new ReentrantLock();
condition2 = lock.newCondition();
condition3 = lock.newCondition();
}
public void first(Runnable printFirst) throws InterruptedException {
lock.lock();
printFirst.run();
num = 2;
condition2.signal();
lock.unlock();
}
public void second(Runnable printSecond) throws InterruptedException {
lock.lock();
while (num != 2) {
condition2.await();
}
printSecond.run();
num = 3;
condition3.signal();
lock.unlock();
}
public void third(Runnable printThird) throws InterruptedException {
lock.lock();
while (num != 3) {
condition3.await();
}
printThird.run();
lock.unlock();
}
}