链接网站开发需要多少钱十堰微网站建设费用
问题要求:
有三个线程 A、B、C,分别调用 first()、second()、third(),但必须保证:
- first()先执行,
- 然后 second(),
- 最后 third()。
- 但由于线程是并发执行的,操作系统可能会随机调度它们的顺序,所以需要强制让它们按顺序执行。
方法 1:
用 volatile 变量(最简单)
思路:
- 设置一个变量 flag,用来标记当前应该执行哪个方法。
- first()执行完后,修改- flag,告诉- second()可以运行了。
- second()执行完后,修改- flag,告诉- third()可以运行了。
代码:
public class Foo {    
private volatile int flag = 1;// 1表示first可以执行,2表示second,3表示third    public void first() {        System.out.print("first");        flag = 2; // 告诉second可以执行了    }    public void second() throws InterruptedException{        while (flag != 2) {            // 如果flag不是2,就循环等待       }        System.out.print("second");        flag = 3; // 告诉third可以执行了   }    public void third() throws InterruptedException {        while (flag != 3) {           // 如果flag不是3,就循环等待       }       System.out.print("third");    }}
解释:
- volatile保证- flag的修改对所有线程可见(避免缓存问题)。
- second()和- third()会不断检查- flag,直到- flag变成它们需要的值才执行。
缺点:
- while循环会占用 CPU(忙等待),不太高效。
方法 2:
用 synchronized + wait/notify(更高效)
思路:
- 用 synchronized加锁,保证同一时间只有一个线程能进入关键代码。
- wait()让线程等待,- notifyAll()唤醒其他线程。
代码:
public class Foo {    
private boolean firstDone = false;    
private boolean secondDone = false;    
private final Object lock = new Object(); // 锁对象    public void first() {        
synchronized (lock) {            
System.out.print("first");           firstDone = true;            lock.notifyAll(); // 唤醒所有等待的线程        }    }    public void second() throws InterruptedException {        
synchronized (lock) {            while (!firstDone) {                lock.wait(); // 如果first没执行完,就等待            }            System.out.print("second");            secondDone = true;            lock.notifyAll(); // 唤醒third        }    }    public void third() throws InterruptedException {        synchronized (lock) {            while (!secondDone) {                lock.wait(); // 如果second没执行完,就等待            }           System.out.print("third");        }    }}
解释:
- synchronized保证同一时间只有一个线程能进入- lock保护的代码块。
- wait()会让线程释放锁并等待,直到被- notifyAll()唤醒。
- first()执行完后,- notifyAll()会唤醒- second(),- second()执行完后唤醒- third()
优点:
- 比 volatile更高效,因为wait()不会占用 CPU。
方法 3:
用 CountDownLatch(推荐)
思路:
- CountDownLatch是一个计数器,初始值为 1。
- await()会阻塞线程,直到计数器变成 0。-- countDown()会让计数器减 1。
代码:
import java.util.concurrent.CountDownLatch;
public class Foo {    
private CountDownLatch latch1 = new CountDownLatch(1); 
// first -> second    
private CountDownLatch latch2 = new CountDownLatch(1); 
// second -> third    
public void first() {        
System.out.print("first");        
latch1.countDown(); // 让second可以执行    
}    
public void second() throws InterruptedException {        
latch1.await(); // 等待first执行完        
System.out.print("second");        
latch2.countDown(); // 让third可以执行    
}    
public void third() throws InterruptedException {        
latch2.await(); // 等待second执行完        
System.out.print("third");    }
}
解释:
- latch1控制- first()->- second():
- first()执行完后,- latch1.countDown(),- latch1变成 0,- second()的- await()就会放行。
- latch2控制- second()->- third():
- second()执行完后,- latch2.countDown(),- latch2变成 0,- third()的- await()就会放行。
优点:
- 代码简洁,适合这种固定顺序的线程控制。
方法 4:
用 Semaphore(信号量)
思路:
- Semaphore可以控制同时访问的线程数量。
- 初始值为 0 的信号量,acquire()会阻塞,直到release()被调用。
代码:
import java.util.concurrent.Semaphore;
public class Foo {    
private Semaphore sem1 = new Semaphore(0); 
// first -> second    
private Semaphore sem2 = new Semaphore(0); 
// second -> third    
public void first() {        
System.out.print("first");        
sem1.release(); // 让second可以执行    
}    
public void second() throws InterruptedException {        
sem1.acquire(); // 等待first执行完        
System.out.print("second");        
sem2.release(); // 让third可以执行    
}    
public void third() throws InterruptedException {        
sem2.acquire(); 
// 等待second执行完        
System.out.print("third");    }}
解释:
- sem1控制- first()->- second():
- first()执行完后- sem1.release(),- second()的- sem1.acquire()就会放行。
- sem2控制- second()->- third(): -- second()执行完后- sem2.release(),- third()的- sem2.acquire()就会放行。
优点:
- 灵活,适合更复杂的线程控制。
推荐:
- 如果是面试或简单场景,用 CountDownLatch或volatile。
- 如果需要更灵活的控制,用 Semaphore或synchronized。
