Java 指定线程的信号量增量计数

Java semaphore increment count with specified threads

有人知道为什么在编译这段代码后,(我认为)一个线程仍在等待什么吗? 我想用 id 为 10,11 和 12 的线程一个接一个地递增计数,直到 50。 最后,它工作了,但是红色按钮(终止)仍然是红色的,这意味着程序它仍然是 运行,并且可能在等待什么。

我认为当计数为 50 时,return 应该工作并退出方法。也许是,但还不够。

代码如下:

public class App12 {

    Semaphore sem1 = new Semaphore(1);
    Semaphore sem2 = new Semaphore(0);
    Semaphore sem3 = new Semaphore(0);

    int count = 0;

    public void inc() throws InterruptedException {

        while (true) {
            if (Thread.currentThread().getId() == 10) {
                sem1.acquire();
                if (count != 50) {
                    count++;
                    System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);

                    sem2.release();
                } else
                    return;
            }

            if (Thread.currentThread().getId() == 11) {
                sem2.acquire();
                if (count != 50) {
                    count++;
                    System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);

                    sem3.release();
                } else
                    return;

            }

            if (Thread.currentThread().getId() == 12) {
                sem3.acquire();
                if (count != 50) {
                    count++;
                    System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);

                    sem1.release();
                } else
                    return;

            }
        }
    }

    public static void main(String[] args) {

        App12 ap = new App12();
        for (int i = 0; i < 3; i++) {
            Thread th1 = new Thread(new Runnable() {
                public void run() {
                    try {
                        ap.inc();
                        // dec3();

                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }
            });
            th1.start();

        }
    }
}

你的问题是你永远不会释放线程上的锁,它们最终会永远等待。

按照你的逻辑,线程A释放B释放C。

但是,一旦达到 50,线程 A returns。从不释放线程 B 和 C。

所以你需要的是一个释放所有其他等待线程的退出条件。

例如(在你的 while 循环中):

if(count == 50) {
                sem2.release();
                sem3.release();
                sem1.release();
            }

问题是,一旦增加 11 或 12,它们就会立即再次进入循环,此时它们会锁定等待释放的信号。但是,如果您的计数是 50,则释放它的线程将 return 而不会进入您的 if 条件。

或者,您应该能够在 else 子句上添加释放,以便释放所有线程。

希望对您有所帮助,

阿图尔

编辑:这是您实施修复的完整代码:

public class App12 {

    Semaphore sem1 = new Semaphore(1);
    Semaphore sem2 = new Semaphore(0);
    Semaphore sem3 = new Semaphore(0);

    int count = 0;

    public void inc() throws InterruptedException {

        while (true) {

            if (Thread.currentThread().getId() == 10) {
                sem1.acquire();
                if (count != 50) {
                    count++;
                    System.out.println("Thread " + Thread.currentThread().getId() + " has incremented " + count);
                    sem2.release();
                } else {
                    sem2.release();
                    return;
                }
            }

            if (Thread.currentThread().getId() == 11) {
                sem2.acquire();
                if (count != 50) {
                    count++;
                    System.out.println("Thread " + Thread.currentThread().getId() + " has incremented " + count);
                    sem3.release();
                } else {
                    sem3.release();
                    return;
                }

            }

            if (Thread.currentThread().getId() == 12) {
                sem3.acquire();
                if (count != 50) {
                    count++;
                    System.out.println("Thread " + Thread.currentThread().getId() + " has incremented " + count);
                    sem1.release();
                } else {
                    sem1.release();
                    return;
                }
            }

        }
    }

    public static void main(String[] args) {

        App12 ap = new App12();
        for (int i = 0; i < 3; i++) {
            Thread th1 = new Thread(new Runnable() {
                public void run() {
                    try {
                        ap.inc();
                        // dec3();
                        System.out.println("Exist ");
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }
            });
            th1.start();
        }
    }
}

注意:一旦计数达到 50,我将释放信号器,以便其他线程可以退出。

释放锁以完成线程。

import java.util.concurrent.Semaphore;

public class App12 {

Semaphore sem1 = new Semaphore(1);
Semaphore sem2 = new Semaphore(0);
Semaphore sem3 = new Semaphore(0);


int count = 0;

public void inc() throws InterruptedException {

    while (true) {

        if (Thread.currentThread().getId() == 10) {
            sem1.acquire();
            if (count != 50) {
                count++;
                System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);

            } else {
                sem2.release();
                return;
            }
            sem2.release();

        }

        if (Thread.currentThread().getId() == 11) {
            sem2.acquire();
            if (count != 50) {
                count++;
                System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);

            } else {
                sem3.release();
                return;
            }
            sem3.release();
        }

        if (Thread.currentThread().getId() == 12) {
            sem3.acquire();
            if (count != 50) {
                count++;
                System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count);

            } else {
                sem1.release();
                return;
            }
            sem1.release();

        }

    }

}

public static void main(String[] args) {

    App12 ap = new App12();

    for (int i = 0; i < 3; i++) {
        Thread th= new Thread(new Runnable() {
            public void run() {
                try {
                    ap.inc();
                    // dec3();

                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        });
        th.start();
    }
}
}