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

时间:2016-09-16 10:19:44

标签: java multithreading count semaphore

有没有人知道为什么在编译这段代码后,(我认为)还有一个线程在等待什么? 我想用ID为10,11和12的线程逐一增加计数,直到50。 最后,它工作,但红色按钮(终止)仍然是红色,这意味着它仍在运行的程序,可能还在等待一些东西。

我认为当计数为50时,返回应该起作用并退出方法。也许它确实如此,但还不够。

以下是代码:

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();

        }
    }
}

2 个答案:

答案 0 :(得分:1)

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

根据您的逻辑,线程A版本B发布C.

但是,一旦你达到50,线程A就会返回。永远不要释放线程B和C.

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

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

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

问题是,一旦11或12增加,他们就会再次进入循环,此时他们会锁定等待被释放的宿舍。如果您的计数为50,则释放它的线程将返回,而不会输入您的if条件。

或者,您应该能够在else子句中添加一个版本,因此所有线程都会被释放。

希望有所帮助,

Artur

编辑:以下是实施修复程序的完整代码:

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,我将释放semathors,以便其他线程可以退出。

答案 1 :(得分:0)

释放锁定以完成线程。

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();
    }
}
}