Java中的信号量

Java中的信号量,java,semaphore,Java,Semaphore,我的代码: public class t3 { static int i = 1; public static void main(String[] args) throws InterruptedException { Semaphore sem = new Semaphore(1); sem.release(); System.out.println(i++); //1 then ++ sem.release(); System.out.pr

我的代码:

public class t3 {

static int i = 1;

public static void main(String[] args) throws InterruptedException {
    Semaphore sem = new Semaphore(1);
    sem.release();
    System.out.println(i++);    //1 then ++
    sem.release();
    System.out.println(i++);    //2
    sem.acquire();
    System.out.println(i++);    //3
    sem.acquire();
    System.out.println(i++);    //4
    sem.acquire();
    System.out.println(i++);    //5
    sem.acquire();
    System.out.println(i++);    //6
    sem.acquire();
    System.out.println(i++);    //7
    }
}
我的输出:

1
2
3
4
5
为什么不是这样:

1
2
3
4
5
6
7

我猜许可证计数器是这样的:0,-1,-2,-1,0,1,然后阻塞。因为你有一个许可证。似乎许可证计数器的工作方式与此相反,它从1开始,然后像1、2、3、2、1、0和block那样运行。(谢谢@JB Nizet)

信号量是权限池。一开始

Semaphore sem = new Semaphore(1)
仅包含一个权限,但由于您使用了两次
release
,因此又添加了两个权限,因此它总共有3个权限。接下来,您调用了
acquire
五次,但由于信号量中只有三个权限,第四次调用
acquire
会让线程等待可用的权限

要更清楚地看到它,请查看此代码中的注释

Semaphore sem = new Semaphore(1); // 1 permission available
sem.release();                    // 2 permissions available after this method
System.out.println(i++); // 1 then ++
sem.release();                    // 3 permissions available after this method
System.out.println(i++); // 2
sem.acquire();                    // 2 permissions available after this method
System.out.println(i++); // 3
sem.acquire();                    // 1 permission available after this method
System.out.println(i++); // 4
sem.acquire();                    // 0 permissions available after this method
System.out.println(i++); // 5

sem.acquire();                    // now thread needs to wait for available permission
System.out.println(i++); // 6
sem.acquire();
System.out.println(i++); // 7

您应该注意到您的进程没有完成,它处于等待状态。
运行下面的代码版本,改变传递给信号量构造函数的初始值,您应该能够感受到这种行为。
您应该注意到,每次调用release()都会增加可用许可, 每次调用acquire()都会减小池的大小

public static void main(String[] args) throws InterruptedException {
    Semaphore sem = new Semaphore(1);

    sem.release();
    System.out.println(sem.availablePermits() + ":" + i++);    //1 then ++
    sem.release();
    System.out.println(sem.availablePermits() + ":" + i++);    //2
    sem.acquire();
    System.out.println(sem.availablePermits() + ":" + i++);    //3
    sem.acquire();
    System.out.println(sem.availablePermits() + ":" + i++);    //4
    sem.acquire();
    System.out.println(sem.availablePermits() + ":" + i++);    //5
    sem.acquire();
    System.out.println(sem.availablePermits() + ":" + i++);    //6
    sem.acquire();
    System.out.println(sem.availablePermits() + ":" + i++);    //7
    }
}

@邹祖:我也不知道,但它就在这里:好吧,伙计们,我的坏:)我不知道它的存在。我不明白的是“信号量有什么不清楚?”:)这可以通过阅读信号量的javadoc来回答。它是另一种方式:1,2,3,2,1,0->阻塞。relase()添加一个许可证。acquire()获取一个许可证,并减少许可证或块(如果没有)的数量。