使用for循环并行执行scala期货

时间:2016-10-07 04:19:11

标签: scala for-loop concurrent.futures

package p1
import scala.util.Failure
import scala.util.Success
import scala.concurrent.Await
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._

object modCheck extends App {

  def getStudentRoolNo(name: String) = Future {
    println("getStudentRoolNo")
    name match {
      case "name1" => 1
      case "name2" => 2
      case _       => throw new Exception("No doesnt exist")
    }
  }

  def getRank(roolNo: Int) = Future {
    println("getRank")
    Thread.sleep(500)
    roolNo match {
      case 1 => "1"
      case 2 => "2"
      case _ => throw new Exception("No roolNo exist")
    }
  }

  def getDetails(roolNo: Int) = Future {
    println("getDetails")
    roolNo match {
      case 1 => "details 1"
      case 2 => "Details 2"
      case _ => throw new Exception("No details exist")
    }
  }

  def getStudentRecord(name: String) = {
    for {
      rollNo <- getStudentRoolNo(name)
      rank <- getRank(rollNo)
      details <- getDetails(rollNo)
    } yield (rank + details)

  }

  getStudentRecord("name1").onComplete {
    case Success(ground) => println(s"got my Details $ground")
    case Failure(ex)     => println("Exception!" + ex)
  }

  Thread.sleep(2000)

}

我想在下面的代码中并行执行函数getrankgetDetails(一旦返回getStudentRollNo)。我怎样才能做到这一点?

我在下面尝试,似乎它仍然按顺序执行

请让我知道,如何并行执行

3 个答案:

答案 0 :(得分:1)

未来在创建时开始计算。

for (a <- x; b <- y) yield ???x.flatMap(a => y.map(b => ???))所取代 <{1}}和flatMap()在Future完成后执行它的参数。

map()可以在完成getDetails()之前通过分离getRank()Future调用的创建来开始。

flatMap()

答案 1 :(得分:0)

正如你可能猜到的那样,你的当前代码并没有并行调用getRank和getDetails,因为它内部的for-comprehension。它是public class SavedLists extends AppCompatActivity { // private yourListNumber[] mHoles = new yourListNumber[0]; public static final ArrayList<ListRow> mListRow = new ArrayList<ListRow>(); RecyclerAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_saved_lists); Button mButton = (Button) findViewById(R.id.addList); //RECYCLERADAPTER set-up here: final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); final RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(layoutManager); mAdapter = new RecyclerAdapter(mListRow); recyclerView.setAdapter(mAdapter); mButton.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ mListRow.add(new ListRow()); mAdapter.notifyDataSetChanged(); } }); } } 操作的语法糖。为了实现并行性,你需要在for-comprehension之外创建两个期货。

map

答案 2 :(得分:0)

您可以在for-comprehension中使用zip并行运行两个期货:

  def getStudentRecord(name: String) = {
    for {
      rollNo <- getStudentRoolNo(name)
      rankRollNo <- getRank(rollNo) zip getDetails(rollNo)
    } yield rankRollNo
  }

在上面getRankgetDetails同时运行,结果是一个字符串元组。如果要生成单个字符串,则需要将rankRollNo分隔为单独的组件:

yield rankRollNo._1 + rankRollNo._2