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

java多线程编程、最佳实践和代码

java多线程编程、最佳实践和代码,java,multithreading,Java,Multithreading,我正在写一个文件,在网上对不同的地点进行大量的呼叫,这是一个要求的一部分 我的问题是这样的: 假设我有一个main方法,并想调用其他方法: public static void main(String args[]){ //how do I break stuff into threads here Thread nameThread1 = new(fileName.DoMethod1(x)) Thread nameThread2 = new(fileName.DoM

我正在写一个文件,在网上对不同的地点进行大量的呼叫,这是一个要求的一部分

我的问题是这样的:

假设我有一个main方法,并想调用其他方法:

public static void main(String args[]){
    //how do I break stuff into threads here
     Thread nameThread1 = new(fileName.DoMethod1(x))
     Thread nameThread2 = new(fileName.DoMethod2(x))
     Thread nameThread3 = new(fileName.DoMethod3(x))
     Thread nameThread4 = new(fileName.DoMethod4(x))
     Thread nameThread5 = new(fileName.DoMethod5(x))
}



           //fileName.java
public static void doMethod1(object){
   //Do Method Stuff
}

public static void doMethod2(object){
   //Do Method Stuff
}
我已经阅读了一些关于如何实现它的指南,但我仍然对实现它的确切方法感到困惑


如果可能的话,有人能给我举一些例子吗?谢谢

您不能像在帖子中那样调用不同的方法。您可以调用不同的类:

public static void main(String args[]){
     Thread nameThread1 = new Thread(new Method1(x));
     nameThread1.start();
     Thread nameThread2 = new Thread(new Method2(x));
     nameThread2.start();
     Thread nameThread3 = new Thread(new Method3(x));
     nameThread3.start();
     Thread nameThread4 = new Thread(new Method4(x));
     nameThread4.start();
     Thread nameThread5 = new Thread(new Method5(x));
     nameThread5.start();
}

public class Method1 implements Runnable {
   private Object obj;
   public Method1(Object obj) {
       this.obj = obj;
   }
   //fileName.java
   public void run(){
      //Do Method Stuff
   }
}

您应该始终考虑使用CREATEXECUTROR服务代码来管理这样的作业。例如:

// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newCachedThreadPool();
threadPool.submit(new Method1(x));
threadPool.submit(new Method2(x));
...
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
如果必须使用一个类,则可以启动一个使用开关或其他东西的Runnable:

public static void main(String args[]){
     Thread nameThread1 = new Thread(new Method(1, x));
     nameThread1.start();
     Thread nameThread2 = new Thread(new Method(2, x));
     nameThread2.start();
     ...
}
public class Method1 implements Runnable {
   private int which;
   private Object obj;
   public Method1(int which, Object obj) {
       this.which = which;
       this.obj = obj;
   }
   //fileName.java
   public void run(){
       switch(which) {
          case 1:
             doMethod1(obj);
             break;
          case 2:
             doMethod2(obj);
             break;
          ...
       }
    }
    private void doMethod1(Object obj){
       ...
    }
    private void doMethod2(Object obj){
       ...
    }
}
但是执行器或单独的Runnable类会更干净。

线程需要Runnable的实例,所以您可以创建一个实现Runnable的类,然后您传递它必须响应的命令,然后根据您选择调用哪个方法的命令

public class MyRunnable implements Runnable {

   public MyRunnable(String commandToExecute){
      this.command = commandToExecute;
   }

   public void run() {
      //depending on command call specific methods.
   }
}
这种方法的一个缺点是run方法的if-else列表太长,无法检查要调用哪个方法

好处是,如果所有方法都与一个类相关,并且将它们放在单独的类中没有意义,则不会创建不必要的类


另一种方法是按照Gray的建议为每个方法创建单独的类,而不是直接创建特定类的实例,您可以使用Factory模式为您创建实例。

如果您必须执行大量调用,最好的解决方案是实例化线程池并将其用于所有任务。稍后,您将根据您的机器拥有的处理器/内核数量对其进行调整。下面是一个使用ThreadPoolExecutor的非常简单的实现:


很多人建议您使用Runnable,但我建议您使用callable,因为Runnable不返回结果,也不能抛出选中的异常。要更好地组织代码并能够抛出异常或从方法返回值,请使用callable。此外,出于您的目的,请使用一些池执行器来执行此工作。以下是我对设计的看法-

编写一个可调用类,并根据请求参数调用适当的方法

私有类GetAndProcessResponse实现可调用{ 私人最终请求; 私人最终倒计时锁存器倒计时锁存器

    GetAndProcessResponse(final Request request, final CountDownLatch countDownLatch) {
        this.request = request;
        this.countDownLatch = countDownLatch;
    }

    public ProcessedResponse call() {
        try {
            // do a switch case on request params
            // and call appropriate methods.
        } finally {
            countDownLatch.countDown();
        }
    }
}
使用倒计时闩锁获取作业完成状态

不要调用join,因为您需要使用executor服务

使用future.gettimeout,因为它是一个网络作业,需要在一段时间后进行剪切


这可能是我在SO上见过的最好的答案。哇,谢谢@Damien。很容易回答正确的问题。:-没错,虽然不难,但你们在源代码和解释方面做得很好。以防万一有人感兴趣;代码很好,除了最后一个例子是为什么你们需要GenericThreadPool类?为什么不使用JUt使用ExecutorService?这似乎过于复杂,没有明显的原因。因为这样,你可以使用一个单实例在整个应用程序中共享同一个线程池。在我看来,这是一个控制线程数量的好方法。不过,也许有更好的方法。
public class MyJob implements Runnable {
   public void run(){
      // Do your job here...
   }
}

GenericThreadPool pool = GenericThreadPool.getInstance();
pool.execute(new MyJob());
    GetAndProcessResponse(final Request request, final CountDownLatch countDownLatch) {
        this.request = request;
        this.countDownLatch = countDownLatch;
    }

    public ProcessedResponse call() {
        try {
            // do a switch case on request params
            // and call appropriate methods.
        } finally {
            countDownLatch.countDown();
        }
    }
}