セマフォを使用していくつかのスレッドを同期しようとしています。目標は、1 (8 回)、2 (4 回)、4 (2 回)、8 (1 回) のシーケンスをこの順序で繰り返し印刷することです。私のプログラムは、約 90% 完了するまでは正しく動作しますが、2 と 4 でうまくいきません。何が問題を引き起こしているのか、一生わかりません。助言がありますか?
public class ThreadSync
{
private static int count = 100;
private static Semaphore printSomeOnes = new Semaphore(1);
private static Semaphore printSomeTwos = new Semaphore(0);
private static Semaphore printSomeFours = new Semaphore(0);
private static Semaphore printSomeEights = new Semaphore(0);
private static boolean runFlag = true;
public static void main( String[] args ) {
// create and start each runnable
Runnable task1 = new TaskPrint1();
Runnable task2 = new TaskPrint2();
Runnable task3 = new TaskPrint4();
Runnable task4 = new TaskPrint8();
Thread thread1 = new Thread( task1 );
Thread thread2 = new Thread( task2 );
Thread thread3 = new Thread( task3 );
Thread thread4 = new Thread( task4 );
thread1.start();
thread2.start();
thread3.start();
thread4.start();
// Let them run for 500ms
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// put up the stop sign
runFlag=false;
thread4.interrupt();
thread3.interrupt();
thread2.interrupt();
thread1.interrupt();
}
public static class TaskPrint1 implements Runnable
{
public void run(){
while (runFlag) {
for(int i = 0; i < count; i++){
if(i % 8 == 0){
try {
printSomeOnes.acquire();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.printf( "%s\n", "1");
if(i % 8 == 0){
printSomeTwos.release();
}
}
}
}
}
public static class TaskPrint2 implements Runnable
{
public void run(){
while (runFlag) {
for(int i = 0; i < count; i++){
if(i % 4 == 0){
try {
printSomeTwos.acquire();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.printf( "%s\n", "2");
if(i % 4 == 0){
printSomeFours.release();
}
}
}
}
}
public static class TaskPrint4 implements Runnable
{
public void run(){
while (runFlag) {
for(int i = 0; i < count; i++){
if(i % 2 == 0){
try {
printSomeFours.acquire();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.printf( "%s\n", "4");
if(i % 2 == 0){
printSomeEights.release();
}
}
}
}
}
public static class TaskPrint8 implements Runnable
{
public void run(){
while (runFlag) {
for(int i = 0; i < count; i++){
try {
printSomeEights.acquire();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.printf( "%s\n", "8");
printSomeOnes.release();
}
}
}
}
}