如何在Java中将特定数量的线程限制到同步块中

3
我无法理解这个问题。在多线程环境中,只有三个线程能够执行同步块,其余的线程应该等待吗?
我的理解是,当我们使用同步或监视器时,一个线程将等待另一个线程完成同步块或方法的执行。为了实现多个线程进入同步块或方法,我们需要使用wait()、notify()、notifyAll(),即线程间通信,其中wait()方法在某个对象上调用时,它会获取它的锁并给其他等待线程机会。
因此,我想知道如何解决上述问题。我不确定是否已经正确提出了我的问题。如果可能的话,我们需要使用java concurrent util包还是可以在基本(核心)线程功能中完成。

1
你可能正在寻找一个信号量 - OldCurmudgeon
为什么你要这样做?这听起来像是应该用另一种方式解决的问题。 - Peter Lawrey
我被一个朋友问到了这个问题。现在我已经掌握了信号量的概念。 - Bhupati Patel
2个回答

6

使用三个许可证的信号量:

信号量常用于限制能够访问某些(物理或逻辑)资源的线程数量。


3
使用信号量可能是解决您问题的最佳方案,但尝试自己的解决方案也无妨,即使只是出于实验和学习新知识的目的。
这里是使用LinkedBlockingQueue实现锁的快速示例。此锁仅允许一定数量的线程访问getKey()和returnKey()之间的代码块:
public class Lock {

    private int keys;

    private LinkedBlockingQueue<Integer> q;

    public Lock(int keys) throws InterruptedException {
        q = new LinkedBlockingQueue<>();
        while (q.size() != keys)
            q.put(0);
    }

    public void getKey() throws InterruptedException {
        q.take();
    }

    public void returnKey() throws InterruptedException {
        q.put(0);
    }

    static Lock lck;
    public static void main (String [] args) throws InterruptedException {

        lck = new Lock(3);
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    lck.getKey();
                    Lock.test();
                    lck.returnKey();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };

        for (int t = 0; t < 10; t ++) 
            new Thread(r).start();
    }

    public static void test() throws InterruptedException {
        System.out.println("I am " + Thread.currentThread().getName());
        Thread.sleep(1000);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接