文章目录
1. 使用 join 方法
通过使用 Thread.join 方法,可以确保一个线程在另一个线程完成后再开始执行。
public class JoinExample {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
System.out.println("T1 is running");
});
Thread t2 = new Thread(() -> {
try {
t1.join();
System.out.println("T2 is running");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t3 = new Thread(() -> {
try {
t2.join();
System.out.println("T3 is running");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
t3.start();
}
}
2. 使用 CountDownLatch
通过使用 CountDownLatch,可以确保线程按顺序执行。
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) {
CountDownLatch latch1 = new CountDownLatch(1);
CountDownLatch latch2 = new CountDownLatch(1);
Thread t1 = new Thread(() -> {
System.out.println("T1 is running");
latch1.countDown();
});
Thread t2 = new Thread(() -> {
try {
latch1.await();
System.out.println("T2 is running");
latch2.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t3 = new Thread(() -> {
try {
latch2.await();
System.out.println("T3 is running");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
t3.start();
}
}
3. 使用 Semaphore
使用 Semaphore 可以控制线程的执行顺序。
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static void main(String[] args) {
Semaphore sem1 = new Semaphore(0);
Semaphore sem2 = new Semaphore(0);
Thread t1 = new Thread(() -> {
System.out.println("T1 is running");
sem1.release();
});
Thread t2 = new Thread(() -> {
try {
sem1.acquire();
System.out.println("T2 is running");
sem2.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t3 = new Thread(() -> {
try {
sem2.acquire();
System.out.println("T3 is running");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
t3.start();
}
}
4. 使用 ReentrantLock 和 Condition
使用 ReentrantLock 和 Condition 可以更细粒度地控制线程的执行顺序。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockConditionExample {
private static final Lock lock = new ReentrantLock();
private static final Condition condition1 = lock.newCondition();
private static final Condition condition2 = lock.newCondition();
private static boolean t1Finished = false;
private static boolean t2Finished = false;
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
lock.lock();
try {
System.out.println("T1 is running");
t1Finished = true;
condition1.signal();
} finally {
lock.unlock();
}
});
Thread t2 = new Thread(() -> {
lock.lock();
try {
while (!t1Finished) {
condition1.await();
}
System.out.println("T2 is running");
t2Finished = true;
condition2.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
});
Thread t3 = new Thread(() -> {
lock.lock();
try {
while (!t2Finished) {
condition2.await();
}
System.out.println("T3 is running");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
});
t1.start();
t2.start();
t3.start();
}
}
5. 使用 BlockingQueue
通过使用 BlockingQueue 可以控制线程的执行顺序。
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class BlockingQueueExample {
public static void main(String[] args) {
BlockingQueue<String> queue1 = new ArrayBlockingQueue<>(1);
BlockingQueue<String> queue2 = new ArrayBlockingQueue<>(1);
Thread t1 = new Thread(() -> {
System.out.println("T1 is running");
try {
queue1.put("T1 done");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
try {
queue1.take();
System.out.println("T2 is running");
queue2.put("T2 done");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t3 = new Thread(() -> {
try {
queue2.take();
System.out.println("T3 is running");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
t3.start();
}
}
这些方法都可以确保线程按指定顺序执行,选择哪种方法取决于具体的使用场景和需求。