【问题标题】:How to make multiple Threads run at the same time using a for loop in Java?如何使用Java中的for循环使多个线程同时运行?
【发布时间】:2022-01-07 08:18:45
【问题描述】:

我对 java 很陌生,并开始构建一个小程序来查找给定范围内的素数。 现在我尝试实现多任务处理,例如将要检查的数字分成n个部分,分别进行检查。我想让它尽可能灵活,所以我没有在代码中指定线程数,而是使用了一个提示变量。 现在,代码可以运行,但线程不能并行运行。

这里似乎有什么问题?

           [...]     
           System.out.println("How many Threads shall be used?");
           int b1 = scan.nextInt();
           scan.close();
           for (int i = 1; i <= b1; i++) {
             long u = (q/b1)*(i-1);
             long o = (q/b1)*i;
             System.out.println("Thread "+i+" started.");
             Thread t1 = new Thread(new thread1 (u, o, i));
             t1.start();
           }


class thread1 implements Runnable{
    public thread1 (long a, long b, int c) {
//a= min. number, b = max. number, c=number of Thread
        primefinder.findPrimes(b,a, c);
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
    }
}

【问题讨论】:

  • 你应该把你的工作放在 run 方法中。据我所知,您在 thread1 构造函数中进行计算。通过放入构造函数,您可以在主(调用)线程上完成所有工作,而当调用t1.start 时,它不会做任何事情,因为run 方法中没有定义任何内容。

标签: java multithreading


【解决方案1】:

来自 javadoc https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html

class PrimeRun implements Runnable {
         long minPrime;
         PrimeRun(long minPrime) {
             this.minPrime = minPrime;
         }

         public void run() {
             // compute primes larger than minPrime
              . . .
         }
     }
    

您的逻辑必须在 run() 方法中。正是这个方法将被调用并在另一个线程上运行。 使用您的实际代码,您在 Runnable 的构造函数中进行计算,该构造函数在您的 for 循环中调用,因此是顺序的。

将您的计算转移到运行方法将解决问题。

编辑:如果您难以将参数传递给您的计算代码,您可以简化为:

Thread t1 = new Thread(() -> findPrimes(u, o, i));
t1.start();

它做同样的事情,在底层,它创建了一个匿名类来实现 Runnable 接口,该接口在类字段中捕获你的变量。

【讨论】:

  • 就是这样,谢谢!我按照描述的方式尝试了它,因为我没有设法将参数传递给 run() 方法。
  • 你也可以使用 lambda 表达式,我在答案中添加了一个示例
【解决方案2】:

正如正确的Answer by Daniel 所说,您需要将业务逻辑移动到Runnablerun 方法或Callablecall 方法中以获取通过Future 返回的值.

此外,在现代 Java 中,我们很少直接处理 Thread 类。而是使用 Executors 框架。

ExecutorService es = Executors.newFixedThreadPool( x ) ;
for( … ) { es.submit( task ) ; }
es.shutdown() ;
es.awaitTermination( … ) ;

这已经在 Stack Overflow 上讨论过很多次了。所以搜索以了解更多信息。

【讨论】:

  • 对,完全同意,更进一步的更好的方法是使用 Future API,因为计算素数而不返回结果是..没用的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-25
  • 2012-03-28
  • 2011-09-07
  • 2019-03-09
  • 1970-01-01
  • 2011-02-13
  • 2021-02-18
相关资源
最近更新 更多