2016-04-05 7 views
1

のための並列からのアクセス配列Iは、次のコードがありますスカラ - スレッドセーフな方法で

//variable arrayToAccess is an array of integers 
//anotherArray holds integers also 
anotherArray.par.foreach{ item => 
    val mathValue = mathematicalCalculation(item) 
    if (mathValue > arrayToAccess.last) { 
     //append element 
     arrayToAccess :+= mathValue 
     //sort array and store it in the same variable 
     arrayToAccess = arrayToAccess.sortWith((i1,i2) => i1 > i2).take(5) 
    } 
} 

を私はそのようにarrayToAccess変数へのアクセスはスレッドセーフではないと思われます。どのようにスレッドセーフな方法で上記のコードを実装できますか?また、anotherArray.parの並列性のレベルを制御することはできますか(たとえば、8つのうち2つのコアのみを使用できます)。そうでない場合、それを制御する方法はありますか?

答えて

2

あなたはそれを考えすぎています。 ちょうど行います

arrayToAccess = anotherArray.par 
    .map { mathematicalCalculation _ } 
    .seq 
    .sorted 
    .reverse 
    .take(5) 

をそれはあなたのコードがすることを意図しているのと同じ結果が得られますが、スレッドセーフです。

更新ソート・ステップがかかる時間を心配している場合、あなただけの代わりに線形時間でトップ5を選択することができます:

並列処理の設定について
val top(data: Array[Int], n: Int) = { 
val queue = PriorityQueue()(Ordering[Int].reverse) 
data.fold(queue) { case(q,n) => 
    q.enqueue(n) 
    while(q.size > 5) q.dequeue 
    queue 
} 
.toArray 
.sorted 
.reversed 

を、私はこれは役立つはず、と思う:http://docs.scala-lang.org/overviews/parallel-collections/configuration

更新あなたがソートステップを懸念している場合、あなたは並列ソートでそれを置き換えることができたり、次のように、線形時間で区切られたプライオリティキューに折り畳ま:

def topN(data: Array[Int], n: Int) = {  
    val queue = PriorityQueue()(Ordering[Int].reverse) 
    data.foldLeft(queue) { case (q, x) => 
    q.enqueue(x) 
    while(q.size > n) q.dequeue 
    q 
    }.dequeueAll.reverse 
+0

'.seq.sorted.reverse.take(5)' – Aivean

+0

@Aiveanありがとうございます。一定。 – Dima

+0

anotherArray変数が大きい場合、ソートされたメソッドと逆のメソッドには時間がかかりますが、そうではありませんか?特にそれがより複雑なソート方法である場合。 –

関連する問題