在 Java 中使用线程和信号量 - "acquire()"如何工作?



我目前正在参加一门针对"高级"(按照我们大学CS项目的标准)程序员的Java入门课程。虽然到目前为止,我们处理过的概念都没有完全不同,但我对信号量的实用性感到困惑——我应该使用一个(或多个?)信号量来确保在任何给定时间只有五个线程按顺序执行。由于我现在的处境,我现在无法测试我的程序是否朝着正确的方向前进,但我只需要弄清楚Semaphore.acquire()是如何工作的:

既然"acquire()"是信号量的方法,并且它不以线程(或任何东西)为参数,那么如何"选择"一个线程来获得许可呢?它是否会自动将许可证应用于之前引用的线程?这基本上就是我现在尝试的方式:

Thread selected = threads[int next_thread_to_add];
mySemaphore.acquire();

有一个简单的Semaphore示例。通过使用Semaphore,您可以传递一个Semaphore对象来决定有多少线程可以并发运行。

public class Test implements Runnable {
    Semaphore semaphore;
    public Test(Semaphore semaphore) {
        this.semaphore = semaphore;
    }
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(1);
        Thread thread1 = new Thread(new Test(semaphore));
        Thread thread2 = new Thread(new Test(semaphore));
        Thread thread3 = new Thread(new Test(semaphore));
        Thread thread4 = new Thread(new Test(semaphore));
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
    }
    @Override
    public void run() {
        try {
            semaphore.acquire();
            System.out.println("Hello World: " + Thread.currentThread().getName());
            semaphore.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

当前正在运行的调用mySemaphoer.acquire()的线程获得许可。你不选择线程,信号量会选择,‘selected’线程只是通过Acquired()调用。其他人等待,直到他们成为"选定"

既然"acquire()"是信号量的方法,并且它不以线程(或任何东西)为参数,那么如何"选择"一个线程来获得许可呢?

在执行要同步的代码块之前,您需要使用信号量.aquire()方法。在同步代码块的末尾,使用.release()方法,以便另一个线程可以获取信号量。

它是否会自动将许可证应用于之前引用的线程?

不,任何正在运行的线程都会在到达mySemaphore.acquire();行时尝试从Semaphore获取()许可。

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html#acquire()

与使用信号量或锁时的情况一样,要小心避免死锁。

最新更新