2010-05-04 18 views
10

Ağ uygulamalarının çoğullamayı neden kullanacağını (çok fazla iş parçacığı oluşturmamak için) ve programların niçin asenkron çağrıları (daha verimli) arama için kullanacağını anlayabiliyorum. Ancak AsynchronousFileChannel'in verimlilik amacını anlamıyorum.Neden Java'nın AsynchronousFileChannel'i kullanıyorsunuz?

Herhangi bir fikrin var mı?

cevap

7

Eşzamansız dosyaları okumak için kullanabileceğiniz bir kanaldır, yani I/O işlemleri ayrı bir iş parçacığı üzerinde yapılır, böylece I/O işlemleri sırasında başka bir şey yapabilirsiniz. olay. Örneğin

: sınıfının read() yöntemleri dosyadan veri okuma sonucu elde etmek için bir Future nesneyi döndürür. Yani, ne yapabilirsiniz read() çağrı, bir Future nesnesi ile hemen geri dönecektir. Arka planda, başka bir iş parçacığı, gerçek verileri dosyadan okuyacaktır. Kendi iş parçacığınız bir şeyler yapmaya devam edebilir ve okunan verilere ihtiyacı olduğunda, Future nesnesinde get() numaralı telefonu arayın. Bu, daha sonra verileri döndürecektir (eğer arka plan iş parçacığı verileri okumayı tamamlamamışsa, veri hazır olana kadar iş parçacığı bloğunuzu yapar). Bunun avantajı, iş parçacığınızın okuma işleminin tüm uzunluğunu beklemek zorunda olmamasıdır; Verilere gerçekten ihtiyaç duyana kadar başka şeyler de yapabilir.

Bkz. the documentation.

Not: AsynchronousFileChannel, Java SE 7'de henüz piyasaya sürülmeyecek yeni bir sınıf olacak.

+0

Teşekkürler ama verimlilik nedenleri hakkında daha fazla merak - I gerçekleştirirken neden göremiyorum/Ç Başka bir iş parçacığında yardımcı olur. Bir iş parçacığı her zaman G/Ç için engellenmelidir ve bildirilen bir kaynak yeniden kullanımı, donanım özellik kullanımı veya herhangi bir performans artırıcı davranış yoktur. –

+9

Bunun avantajı, * iki iş parçacığına * ihtiyacınız olmamasıdır. Büyük bir veri bloğu yazıyorsanız, düşük düzeyde, disk denetleyicisi, tamamlama işleyicinizi çağırmak için yığına giden bir kesintiyi bildirmeden önce diske veri yazma işi yapar. İş parçacığınızın bu işlem sırasında engellenmesi gerekmez ve başka şeyler yapabilir. Bir daha az iş parçacığı kullanırsanız, iş parçacığı zamanlayıcı bir daha az iş parçacığını yönetir, java bildirimini kullanmanız gerekmez. Temel olarak, aynı şeyi yapmak için daha az kaynak kullanırsınız. – lenkite

+2

İşletim sistemi, senkronize olmayan IO işlemlerinin yürütüldüğü sırayı da optimize edebilir. Örneğin, bir dosyada eşzamansız olarak gerçekleştirilen çok sayıda bölgeye ait çok sayıda okuyucunuz varsa, OS, tüm işlemleri tam olarak verilen sırayla yürütmekten endişelenmenize gerek olmadan bunları sıralı okumalar halinde gruplandırabilir. –

3

AsynchronousFileChannel'i kullanmanın bir başka beklenmedik nedenine rastladım. Büyük dosyalar arasında rastgele kayıt yönelimli yazma işlemleri gerçekleştirirken (önbelleğe alma fiziksel belleği aşarak her şeye yardımcı olmaz), AsynchronousFileChannel'in normal bir FileChannel'e karşı tek iş parçacıklı modda iki kat fazla işlem gerçekleştirdiğini buluyorum.

En iyi tahminim, senkronize olmayan io Windows 7'de IO ile çakıştığından, NTFS dosya sistemi sürücüsünün, her aramadan sonra bir senkronizasyon noktası oluşturması gerekmediğinde kendi iç yapılarını daha hızlı güncelleyebilmesidir. .

Ben sonuçlar çok FileChannel yakın ve AsynchronousFileChannel performansının hala yarısı (nasıl performans göstereceğini görmek için RandomAccessFile karşı mikro benchmarked.

çok kanallı yazıyor ile ne emin değilim. Bu açık Bir SSD üzerinde Java 7 (SSD, manyetikten daha hızlı bir büyüklük sırasına ve bellekte bulunan daha küçük dosyalarda bir başka büyüklük sırasına göre daha hızlı bir sıralamadır.)

Aynı oranların Linux üzerinde olup olmadığını görmek ilginç olacaktır.

+0

Gerçekten de, dosyalarınızın OS önbelleğine sığmayacak kadar kısa olduğu sürece, G/Ç'larınızın senkronize olup olmadığına bakılmaksızın G/Ç işlemi tamamlanır. Sadece I/O ve hesaplamanızın benzer uzunluklarda olması durumunda 2x hızlanma maks elde edeceğinizi ekleyeceğim. Hesaplama, I/O zamanının sadece küçük bir kısmıysa veya I/O, hesaplamadan ihmal edilebilir şekilde daha kısa ise, üst üste binmek de mantıklı değildir. – Val

3

Asenkronize IO kullanmak için düşünebilmemin temel nedeni daha iyi İşlemciyi kullanır. Bir dosyada bir çeşit işleme gerçekleştiren bazı uygulamalarınız olduğunu düşünün. Ayrıca, dosyada yer alan verileri parça halinde işleyebileceğinizi varsayalım. Eşzamansız IO'yu kullanmazsanız, uygulamanız muhtemelen aşağıdaki gibi davranacaktır:

  1. Veri bloğunu okuyun. Verilerin okunmasını beklemediğinizde bu noktada işlemci kullanımı yok.
  2. Sadece okuduğunuz verileri işleyin. Bu noktada, uygulamanız verileri işlerken CPU döngülerini tüketmeye başlayacaktır.
  3. Okunacak daha fazla veri varsa, # 1.

İşlemci kullanımı yukarı ve ardından sıfıra, sonra yukarı ve sonra sıfıra, .... İdeal olarak, uygulamanızın verimli olmasını ve verileri olabildiğince hızlı bir şekilde işlemesini istiyorsanız boşta kalmak istemezsiniz. Daha iyi bir yaklaşım olacaktır:

  1. Sayı zaman uyumsuz zaman uyumsuz sonra süreç verilerini

okumak ve bir sonraki okuma sorunu tamamlandığında

  • ilk adım ön yüklemeyi okuyun. Henüz verileriniz yok, bu yüzden bir okuma yapmanız gerekiyor. Bundan sonra, bir okumanın tamamlandığını bildirdiğinizde, bir başka async okumazsınız ve ardından verileri işlersiniz. Buradaki fayda şu ki, bir sonraki okuyucunun veri yığınını işlemeyi bitirdiğinizde muhtemelen bittiği için, işlem yapmak için her zaman elinizde veri var ve bu sayede işlemciyi daha verimli kullanıyorsunuz. Okuma işleminiz bittikten sonra işleminiz bitiyorsa, işlenecek daha fazla veriye sahip olmanız için birden çok zaman uyumsuz okuma yapmanız gerekebilir. Böyle Files.newOutputStream() tarafından döndürülen OutputStream olarak kullanmaktadır InterruptibleChannel yanı sıra herhangi bir şey uygulayan beri, FileChannel talihsiz [1] [2] özelliği vardır:

    Nick

  • 0

    Burada hiç kimse söz vardır şey interrupted state'da bulunan bir iş parçacığında gerçekleştirdiği tüm engelleme işlemlerinin (örn. read() ve write()), Channel'un java.nio.channels.ClosedByInterruptException ile kapanmasına neden olacağını unutmayın.

    Bunun bir sorun olduğu yerler için, AsynchronousFileChannel kullanmak, bir çözüm üretmenin olası bir yoludur.

    İlgili konular