scala中最简单的多线程形式

Posted

技术标签:

【中文标题】scala中最简单的多线程形式【英文标题】:Simplest form of multithreading in scala 【发布时间】:2016-06-18 16:11:10 【问题描述】:

所以,我有一部分代码如下所示。

for(a <- 0 until segments)

    // do something with elements at index a

什么是最简单的多线程类型,它可以让我在单独的线程中执行该循环的每个元素。我还有需要由每个线程访问的全局集合(由 a 索引)。我在网上看到的都是期货和演员,但很难掌握。我想要像 OpenMP 这样简单的东西。

我尝试了以下操作,但它给了我错误,';' expected but '.' found. thread.start

for (a <- 0 until segments) 
    val thread = new Thread 
        override def run 
            // do something with elements at index a
         thread.start

【问题讨论】:

docs.scala-lang.org/overviews/core/futures.html 不确定你真正想要什么,但Future.traverse 也许平行收藏会适合你?它不会在单独的线程上执行每个元素,但会合理地拆分工作以使用所有内核。 我不想使用并行集合,因为这需要我更改大量代码。 您的意思是“最简单”是“最短”还是“低级”? 【参考方案1】:

我假设您执行代码只是为了产生副作用。

以下代码有效。您会收到一个错误,因为 thread.start 应该在单独的行中。

for (a <- 0 until 10) 
    val thread = new Thread 
        override def run(): Unit =  
            // code
        
    
    thread.start()

您可以使用期货替换它,以使用比产生大量线程更好的线程池。

for (a <- 0 until 10) 
    Future 
        // code
    

但是,无论哪种情况,您都不能等到它完成。您可以遍历该范围并取回 Future,其中将包含您使用第二个函数开始的每个期货的所有部分结果的列表。

val result: Future[List[Unit]] = Future.traverse((0 until 10).toList)(index => Future 
    // code
)

拥有Future 结果,您可以等待它,即阻塞调用线程,直到所有计算完成。

import scala.concurrent.duration._
import scala.concurrent.Await
Await.ready(result, 1.hour)

使用Await.result 得到结果,Await.ready 只是等到未来完成。

要等待线程,您需要在启动它们时建立一个列表,然后在每个线程上调用join

我认为您不需要更改现有代码来使用并行集合,但也许我不知道您的代码有什么特定的东西。以下代码会将范围拆分为并行处理的块。

for (a <- (0 until 10).par) 
   // code

使用无需等待的并行集合,线程将被阻塞,直到处理完所有内容。

【讨论】:

你的意思是不能等待。我需要添加什么代码才能等待? 我编辑了我的答案。如果您不等待,您将不知道计算何时完成。顺便说一句,我今天刚刚完成了一门关于 scala 并行编程的精彩课程:p coursera.org/learn/parprog1 @Łukasz 你应该在例子中使用Future.successful 我相信这绝对是我不应该做的事情,因为 OP 想要在多个线程中执行。【参考方案2】:

您对并行集合的看法是错误的:它们不会要求您更改任何超出您实际想要更改的代码:

 (0 until segments).par.foreach  a =>
    // code
 

【讨论】:

以上是关于scala中最简单的多线程形式的主要内容,如果未能解决你的问题,请参考以下文章

最简单的多线程并发与守护线程与join的运用

Python中的多线程(史上最简单易懂版)

多线程threading模块

一个简单的多线程Python爬虫

一个非常简单的多线程并行 URL 获取(无队列)

.NET Core 多线程的用法,以及用例