Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.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_Memory Management - Fatal编程技术网

Java如何限制作用于方法的线程数

Java如何限制作用于方法的线程数,java,multithreading,memory-management,Java,Multithreading,Memory Management,我的web应用程序中有java方法来执行繁重的文件操作。问题是,如果同时出现5个以上的线程(这将在测试阶段出现),它就会崩溃。我的意思是它不能应付拥挤的交通 这就是为什么我希望一次最多处理5个方法请求的原因,如果第6个请求出现,它将等待前5个请求中的一个完成 public synchronized void add(int value){ File a=new File("D:/heavyFile1"); File b=new File("D:/heavyFile2")

我的web应用程序中有java方法来执行繁重的文件操作。问题是,如果同时出现5个以上的线程(这将在测试阶段出现),它就会崩溃。我的意思是它不能应付拥挤的交通

这就是为什么我希望一次最多处理5个方法请求的原因,如果第6个请求出现,它将等待前5个请求中的一个完成

public  synchronized void add(int value){
      File a=new File("D:/heavyFile1");
      File b=new File("D:/heavyFile2");
      File c=new File("D:/heavyFile3");
      //operation on file
  }

我添加了synchronized关键字,但它一次只处理一个请求,这会导致性能问题,因为每个下一个线程都必须等待它完成。请帮助我。

您可以创建一个
执行器
,并使用
信号灯限制它接受的任务数。大概是这样的:

private final Semaphore semaphore = new Semaphore(4);
ThreadPoolExecutor tp= new ThreadPoolExecutor(...){
      public void execute(Runnable r){
          semaphore.acquire();
          super.execute(r);
      }    
      public void afterExecute(Runnable r, Thread t){
         semaphore.release();  
         super.afterExecute(r,t);
      }
};

您可以创建
执行器
,并使用
信号量
限制它接受的任务数。大概是这样的:

private final Semaphore semaphore = new Semaphore(4);
ThreadPoolExecutor tp= new ThreadPoolExecutor(...){
      public void execute(Runnable r){
          semaphore.acquire();
          super.execute(r);
      }    
      public void afterExecute(Runnable r, Thread t){
         semaphore.release();  
         super.afterExecute(r,t);
      }
};

您可以使用限制为5个线程的
ThreadPool
。在这里,您将创建一个线程池并向其提交一个新线程,以便在类上工作。它只允许您配置的最大线程数同时工作。若出现的线程数超过配置数,则必须等待某个工作线程完成其任务


例如:

您可以使用限制为5个线程的
线程池。在这里,您将创建一个线程池并向其提交一个新线程,以便在类上工作。它只允许您配置的最大线程数同时工作。若出现的线程数超过配置数,则必须等待某个工作线程完成其任务


例如:

创建一个具有固定大小的来执行此操作。

创建一个具有固定大小的来执行此操作。

信号灯。初始化。有5个单元,线程在函数顶部等待,信号在结尾。

信号量。初始化。使用5个单元,让线程在函数顶部等待,并在末尾发出信号。

您可以在执行逻辑内部使用
Executor.newFixedThreadPool
习惯用法

完整示例如下:

public class Main {

    public static void main(String[] args) throws Exception {
        Main m = new Main();
        // simulating a window of time where your method is invoked continuously
        for (int i = 0; i < 11; i++) {
            m.doSomething();
        }
        // shutting down executor when done
        m.terminate();
    }

    ExecutorService executor = Executors.newFixedThreadPool(5);

    // internally submits a new task to the executor
    public void doSomething() {
        executor.submit(new Runnable() {
            @Override
            public void run() {
                long wait = ThreadLocalRandom.current().nextLong(2000);
                try {
                    System.out.printf(
                        "%s is sleeping for %dms.%n", 
                        Thread.currentThread().getName(), 
                        wait
                    );
                    Thread.sleep(wait);
                }
                catch (InterruptedException ie) {
                    // suppressed
                }
                System.out.printf(
                    "%s is doing something!%n", 
                    Thread.currentThread().getName()
                );
            }
        });
    }

    public void terminate() throws Exception {
        executor.shutdown();
    }
}
注意


请参阅重复使用的线程名称,这些是新提交的任务,在池中分配了一个空线程

您可以在执行逻辑内部使用
Executor.newFixedThreadPool
习惯用法

完整示例如下:

public class Main {

    public static void main(String[] args) throws Exception {
        Main m = new Main();
        // simulating a window of time where your method is invoked continuously
        for (int i = 0; i < 11; i++) {
            m.doSomething();
        }
        // shutting down executor when done
        m.terminate();
    }

    ExecutorService executor = Executors.newFixedThreadPool(5);

    // internally submits a new task to the executor
    public void doSomething() {
        executor.submit(new Runnable() {
            @Override
            public void run() {
                long wait = ThreadLocalRandom.current().nextLong(2000);
                try {
                    System.out.printf(
                        "%s is sleeping for %dms.%n", 
                        Thread.currentThread().getName(), 
                        wait
                    );
                    Thread.sleep(wait);
                }
                catch (InterruptedException ie) {
                    // suppressed
                }
                System.out.printf(
                    "%s is doing something!%n", 
                    Thread.currentThread().getName()
                );
            }
        });
    }

    public void terminate() throws Exception {
        executor.shutdown();
    }
}
注意


请参阅重复使用的线程名称,这些是新提交的任务,在池中分配了一个空线程

我看不出这段代码与你的问题有什么关系。我看不出这段代码与你的问题有什么关系。你能不能提供代码,因为我对它一无所知?你能不能提供代码,因为我对它一无所知?如果你能给我一个示例程序,我会非常兴奋,因为我对它一无所知。我不在这里写程序,但写答案。这是你的工作做研究,并使用用户在这里给出的指针。我建议您阅读Oracle官方文档中的并发跟踪:Adam如果您能给我一个示例程序,我会非常激动,因为我对它一无所知。我不是来写程序的,而是来写答案的。这是你的工作做研究,并使用用户在这里给出的指针。我建议您阅读Oracle官方文档中的并发跟踪:Thank@Mena看起来您的解决方案对我有效。Thank@Mena看起来您的解决方案对我有效。