java - 如何在java中将特定数量的线程限制为同步块

Posted

技术标签:

【中文标题】java - 如何在java中将特定数量的线程限制为同步块【英文标题】:How to restrict specific number of threads to synchronized block in java 【发布时间】:2015-02-03 15:11:40 【问题描述】:

我无法弄清楚这个问题。在多线程环境中 - 恰好 3 个线程应该能够执行同步块并且休息应该等待?

我的理解是,当我们使用同步或监控时,一个线程将等到另一个线程在同步块或方法中完成其执行。为了实现多线程进入同步块或方法,我们需要使用 wait()、notify()、notifyAll() 即线程间通信,其中 wait() 方法在某个对象上调用时将获取其锁定并有机会其他等待线程。

所以,我想知道如何做上述问题。我不确定我是否以正确的方式提出了我的问题。如果可能的话,我们需要使用 java concurrent util 包还是可以在基本(核心)线程功能中完成。

【问题讨论】:

您可能正在寻找Semaphore。 你为什么要这样做?这听起来像是一个应该以另一种方式解决的问题。 我的一位朋友问我这个问题。现在我有了信号量的概念。 【参考方案1】:

使用具有三个许可的信号量:

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

【讨论】:

【参考方案2】:

使用信号量可能是解决您的问题的最佳方案,但尝试自己的解决方案并没有什么坏处,即使这只是为了进行试验,也许是为了学习新东西。

这里是一个使用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);
    

【讨论】:

以上是关于java - 如何在java中将特定数量的线程限制为同步块的主要内容,如果未能解决你的问题,请参考以下文章

java基础线程池

Java线程池

Java:在特定队列大小后阻止提交的 ExecutorService [重复]

我可以设置 Java VM 可用的线程/CPU 数量吗?

如何在 Java 中将消息框中的特定单词(变量)设为粗体?

02Java进阶--线程池详解