java 启动3个线程打印递增的数字, 线程1先打印1,2,3,4,5 然后是线程2打印6,7,8,9,10 然后是线程3打印11,12,13,14,15.接着再由线程1打印16,17,18,19,20....依次类推, 直到打印到60
时间: 2023-07-27 22:24:27 浏览: 105
下面是一个可能的Java实现,使用`java.util.concurrent`包中的`Semaphore`和`Lock`实现线程同步:
```java
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class NumberPrinter {
private final int NUM_THREADS = 3;
private final int NUM_PRINTS = 5;
private Semaphore[] semaphores;
private int currentNumber = 1;
private Lock lock = new ReentrantLock();
private Condition[] conditions;
public NumberPrinter() {
// 初始化信号量和条件变量
semaphores = new Semaphore[NUM_THREADS];
conditions = new Condition[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
semaphores[i] = new Semaphore(1);
conditions[i] = lock.newCondition();
}
}
public void printNumbers(int threadId) {
while (true) {
try {
// 获取信号量,只有一个线程可以获取到
semaphores[threadId].acquire();
// 输出数字
for (int i = 0; i < NUM_PRINTS; i++) {
System.out.printf("Thread %d: %d\n", threadId + 1, currentNumber++);
}
// 释放下一个线程的信号量
int nextThreadId = (threadId + 1) % NUM_THREADS;
semaphores[nextThreadId].release();
// 等待自己的信号量被释放
conditions[threadId].await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 释放自己的信号量
semaphores[threadId].release();
}
}
}
public void run() {
// 启动3个线程
for (int i = 0; i < NUM_THREADS; i++) {
final int threadId = i;
new Thread(() -> printNumbers(threadId)).start();
}
// 主线程释放第一个线程的信号量
semaphores[0].release();
// 等待所有线程完成
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
NumberPrinter np = new NumberPrinter();
np.run();
}
}
```
这里使用`Semaphore`来控制线程的同步,每个线程都会等待前一个线程释放自己的信号量才能继续输出数字。使用`Lock`和`Condition`来实现更细粒度的线程同步,每个线程都会等待自己的条件变量被唤醒才能继续执行。在`printNumbers`方法中,每个线程会循环输出五个数字,然后释放下一个线程的信号量,等待自己的信号量被释放。在`run`方法中,主线程释放第一个线程的信号量,然后等待所有线程完成。
阅读全文