每个模式都需要一个信号量。第一个应初始化为 1(因为您希望该线程运行),所有其他应初始化为 0(因为您首先要阻止这些线程)。
每个线程都应该从减小其信号量的值开始(如果信号量的值为 0,则该调用将阻塞)。在线程 1 结束时,您应该增加第二个信号量的值。在线程 2 结束时,您应该增加第 3 个信号量的值,依此类推。在最后一个线程结束时,您应该再次增加第一个信号量的值,重新开始。
由于我不想做你的作业,我将举一个只有 2 个线程的示例:
public static void main(String[] args) {
final Semaphore thread1Block = new Semaphore(1);
final Semaphore thread2Block = new Semaphore(0);
Thread thread1 = new Thread(new Runnable() {
public void run() {
while (true) {
// reduce the value of the first semaphore by one
// blocking if the value is 0
thread1Block.aquire();
System.out.print("11111111");
// increase the value of the second semaphore by one
thread2Block.release();
}
}
});
Thread thread2 = new Thread(new Runnable() {
public void run() {
while (true) {
// reduce the value of the second semaphore by one
// blocking if the value is 0
thread2Block.aquire();
System.out.print("2222");
// increase the value of the first semaphore by one
thread1Block.release();
}
}
});
// start the threads
thread1.start();
thread2.start();
}
编辑
我显然误解了这个问题。棘手的部分是以它们作为计数器的方式使用信号量。我会按照以下方式进行(同样,仅以 2 个线程为例):
public static void main(String[] args) {
final Semaphore s1 = new Semaphore(8);
final Semaphore s2 = new Semaphore(0);
Thread t1 = new Thread(new Runnable() {
public void run() {
while (true) {
s1.acquire();
System.out.print("1");
s2.release(4 * ((8 - s1.availablePermits()) / 8));
}
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
while (true) {
s2.acquire();
System.out.print("2");
s1.release(8 * ((4 - s2.availablePermits()) / 4));
}
}
});
t1.start();
t2.start();
}
诀窍是每个信号量也用作计数器:只有当第一个信号量的值为 0 时,第二个信号量的值才会增加 4。同样,当第二个信号量的值为 0 时,第一个信号量的值增加 8 .