Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用信号量_Java_Multithreading_Semaphore - Fatal编程技术网

Java 使用信号量

Java 使用信号量,java,multithreading,semaphore,Java,Multithreading,Semaphore,我想知道如何使这些线程一个接一个地工作,以及如何使第一个线程始终在第二个线程之后运行。我创建了一个信号量,但我不确定如何使用它 public class A extends Thread { private int i; public A(int x) { i = x; }@ Override public void run() { System.out.println(i); } } /**大体上**/ A c1

我想知道如何使这些线程一个接一个地工作,以及如何使第一个线程始终在第二个线程之后运行。我创建了一个信号量,但我不确定如何使用它

public class A extends Thread {
    private int i;
    public A(int x) {
        i = x;
    }@
    Override
    public void run() {
        System.out.println(i);
    }
}
/**大体上**/

A c1 = new A(5);
A c2 = new A(6);
Semaphore s = new Semaphore(1, true);
c1.start();
c2.start();

new Thread(new Runnable() {
    public void run() {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {}
            System.out.println("+");
        }
    }
}).start();

new Thread(new Runnable() {
    public void run() {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(70);
            } catch (InterruptedException e) {}
            System.out.println("*");
        }

    }
}).start();

您可以将信号量中的许可建模为:allowed to run

因为您希望允许第一个线程自动运行,所以不能对第一个线程使用acquire,因为它将与第二个线程竞争许可。所以第一个线程开始,假设它有许可证。当第一个螺纹完成时,它将释放许可证。第二个螺纹需要获得许可才能开始工作

首先创建一个许可证为零的信号量,因为第一个线程已经隐式拥有一个许可证

final Semaphore s = new Semaphore(0, true);
第一个线程中的最后一行应为:

s.release();
s.acquireUninterruptibly();
请注意,它可以在没有获取的情况下发布-信号量只是计数,它不跟踪谁拥有哪个许可

第二个线程中的第一行应为:

s.release();
s.acquireUninterruptibly();
或者只是获取,但是你需要捕捉中断异常

我想知道如何使这些线程一个接一个地工作,以及 如何使第一个始终在第二个之后运行。我创建了一个信号量,但我不确定如何使用它。 如果希望线程在调用线程c2之前完成,可以在本例中使用join。与此类似,在main的线程中调用线程:

这应该能回答你的问题

我对信号灯有点了解

通常,您不能使用信号量来控制线程的执行顺序。信号量是一个或多个资源的锁。想要访问资源的线程正在相互竞争,您无法控制下一个信号量将向谁授予访问权

我知道另一个答案的诀窍。我没有测试它,它可能会工作,但我认为这不是正确的方法

下面是一个不使用sempahore的示例:

import java.util.concurrent.Semaphore;

class A extends Thread {

    private int i;
    public A(int x) {
        i = x;
    }

    public void run() {
       System.out.println(i);
    }

    public static void main(String[] args) throws Exception {
        A thread1 = new A(5);
        A thread2 = new A(6);
        thread1.start();
        thread1.join();
        thread2.start();
        thread2.join();
    }
}
如果您想使用信号量,尽管我不明白为什么,示例可能如下所示:

import java.util.concurrent.Semaphore;

class A extends Thread {

        private int i;
        final static Semaphore semaphore = new Semaphore(1, true);

        public A(int x) {
            i = x;
        }

        public void run() {
            try {

                /*thread stops here until it gets permit to go on*/
                semaphore.acquire();
                System.out.println(i);
            /*exception must be caught or thrown*/
            } catch (InterruptedException e) { }

            //CRITICAL SECTION

            semaphore.release();

        }

    public static void main(String[] args) throws Exception {
        A thread1 = new A(5);
        A thread2 = new A(6);
        thread1.start();
        thread1.join();
        thread2.start();
        thread2.join();
    }
}

虽然您的问题可以通过线程的“连接”功能解决 可以在启动下一个asi之前强制完成一个线程,如中所示 Elyasian的例子,但仍然有一个必须补充的是,你在正确的轨道上 就信号量路由而言

信号量s=新信号量1,true

在此语句中,设置为“true”的第二个参数称为公平性设置

这确保了先进先出,换句话说,在我们的场景中,先到先得

即首先调用acquire的线程将获得许可并完成 它的任务是第一个线程,只有第二个线程才能继续执行 它的执行

所以你最初的问题是

我想知道如何使这些线程一个接一个地工作,以及如何使第一个线程始终在第二个线程之后运行

可以改为

我想知道如何确保调用acquire的线程
信号量上的第一个总是先运行…

一个接一个=顺序。你为什么想要多个线程?让我练习控制线程这毫无意义。开始第一个线程。加入吧。然后开始第二个线程。那就加入吧。这里没有理由使用信号灯。@SotiriosDelimanolis是正确的。但是,如果你只是想学习信号量,这是一个不错的起点:我不确定你想要实现什么。你能解释一下你想要的执行命令吗?前两行我不清楚。Sry,我不在家。在我的例子中,有c1和c2线程可以用join组织;正如你所说。现在我明白了。但在main中还有两个“新线程”可以自行执行。这里需要信号量,因为没有实例名称可用于连接方法。以您的例子,我也设法控制了它们,谢谢您,先生。在这种情况下,请使用带有公平选项的二进制信号量。如果答案有助于您解决问题,请随时投票并接受。