2015-04-21 28 views
9

Scala'daki varsayılan örtük yürütme bağlamını kullanarak, her yeni gelecek tek bir özel iş parçacığında hesaplanacak mı yoksa hesaplama bölüm havuzunda birden çok iş parçacığına bölünecek ve dağıtılacak mı?Futures tek bir iş parçacığında mı yürütülüyor? (Scala)

Bunun işe yarayıp yaramadığını bilmiyorum, bu sorunun arka planı HtmlUnit API kullanarak birden çok eşzamanlı işlem gerçekleştirmek istiyorum. Bunu yapmak için her yeni WebClient örneğini bir Gelecekte kaydırırdım. Tek sorun, WebClient sınıfının iş parçacığı güvenli olmamasıdır, bu yüzden ayrıldığından ve farklı konulara gönderilebileceğinden endişeleniyorum.

cevap

14

Tek bir iş parçacığı üzerinde bir gelecek yürütülür. Birkaç iş parçacığında birkaç geleceği gerçekleştirilebilir. Yani, geleceğe daha fazla bir şey simültane olarak bir iş parçacığı işgal edebilir.

Nasıl çalışır? Bir Gelecek oluşturduğunuzda, bu, iş parçacığı havuzunuza görev gönderdiğiniz anlamına gelir - bu görev örtülü olarak paralelleştirilemez, dolayısıyla yalnızca bir iş parçacığında yürütülür. Havuza gönderilen bir veya daha fazla görev havuzun kuyruğuna yerleştirilir, bu nedenle yürütücü bu sıradan birer birer görevler alır ve her birini rastgele (veya kasıtlı olarak) seçilen iş parçacığı üzerinde çalıştırır. Bu yüzden birkaç Futures çeşitli konulara gidebilir.

Paylaşılan nesne hakkında - işlemler arasında paylaşılan nesne için güvenli bir şekilde işlem yapmanın tek yolu Executors.newFixedThreadPool(1) kullanıyor, tüm havuz için yalnızca bir iş parçacığı kullanacak. Başka bir çözüm - her gelecek için böyle bir nesneyi klonlamaktır. Oyuncular (paylaşılan nesneyi bir oyuncunun durumuna getir) en iyi seçenek olmalı.

Gelecekte bir nesne kullanırsanız - her şey iyi olmalıdır.

Not: Geleceğin işleyicisi, Future{ ... }.map(handler) gibi, geleceğin kendisinden farklı bir iş parçacığında gerçekleştirilebilir, ancak aslında bir sonuç elde etmek için başka bir Future oluşturur. flatMap için de geçerlidir. Daha doğrusu, eski Geleceğin başarıdan sonra (farklı bir iş parçacığı mümkün) işleyicisi başlatmak için CallbackRunnable oluşturur onComplete kullanmak - Bu geri arama sadece newely oluşturulan geleceği tamamlar, böylece yine "en fazla bir iş parçacığı gelecekte başına"

+0

Teşekkürler! Tam olarak aradığım bilgiler buydu. Sadece hızlı bir takip sorusu - sadece bir iş parçacığı ile newFixedThreadPool çoklu vadeli teslim için herhangi bir avantaj var mı? Tek bir iş parçacığı üzerinde hesaplamalar eşzamanlı olabilir mi? –

+0

Hiçbir performans avantajı yok. Size verebileceği tek şey eşzamansız API'dir (birden fazla görevi gönderin + tamamlanmalarına abone olun). Farklı türden geleceğe yönelik çeşitli havuzlar da oluşturabilirsiniz, ancak aktörler bunun için daha iyidir. – dk14

+1

Implicit val executionContext = ExecutionContext.fromExecutorService (Executors.newFixedThreadPool (1)) 'ile' Executors.newFixedThreadPool (1) 'adlı bir' ExecutionContext 'oluşturun. – jpcooper

-1

A Future[+T] garanti olamaz Birden fazla geleceğe sahip olması durumunda aynı konu üzerinde tamamlanacağını. Bu, aynı anda bir değişiklik istisnası veya bu çizgiler boyunca bir şey elde edeceğiniz anlamına gelmez. Sıralı olarak yürütmek için asenkron kod alabilirsiniz, bu durumda güvenli olacaktır.

İkinci sorunuz için, her bir gelecek için bir örneğiniz olduğu sürece, herhangi bir eşzamanlılık sorununuz olmamalıdır.

+0

eğer besteleyerek ['Future.sequence'] gibi bir şey ifade ederseniz (https://github.com/scala/scala/blob/2.11.x/src/library/scala/concurrent/Future.scala) - sadece boş gövdeli yeni başarılı bir gelecek (böylece hiç bir yerde idam edilmedi) ve daha sonra işleyicileri (bileşendeki geleceğe işleyicileri) ekleyerek. Böylece geleceğin kendisi tek bir iplik içinde idam edilir; Ancak işleyiciler ('Gelecek.map') farklı olanlarda çalıştırılabilir, ancak her yeni işleyici bir * farklı * gelecek – dk14

+0

döndürür. Yani, dizi sadece birkaç yeni gelecek üretiyor, ancak onlardan * tek bir * gelecek birden fazla iş parçacığına atanamaz. – dk14

+0

FlatMap'in kullanımından veya geleceğe yönelik kavrayışlardan bahsediyorum. –