2016-10-22 60 views
1
import java.nio.channels.{AsynchronousServerSocketChannel, AsynchronousSocketChannel} 
import java.net.InetSocketAddress 
import scala.concurrent.{Future, blocking} 

class Master { 
    val server: AsynchronousServerSocketChannel = AsynchronousServerSocketChannel.open() 
    server.bind(new InetSocketAddress("localhost", port)) 

    val client: Future[AsynchronousSocketChannel] = Future { blocking { server.accept().get() } } 
} 

這是我正在嘗試的僞代碼。Scala中的異步IO(套接字)

在問這個問題之前,我搜索了一下,發現一個相關的answer。 在她的回答,我不知道這意味着什麼:"If you want to absolutely prevent additional threads from ever being created, then you ought to use an AsyncIO library, such as Java's NIO library."

因爲我不想(使用blocking時的情況)或thread pool hell(相反的情況),從任一running out of memory苦,她的回答是正是我一直期待。但是,正如您在我的僞代碼中看到的那樣,由於blocking,即使我使用了NIO,她也會爲每個客戶端創建一個新線程(爲簡單起見,我僅創建了一個客戶端)。

  1. 請用一個簡單的例子來解釋她的建議。
  2. 在Scala中嘗試異步io時,我的僞代碼是否是一種合適的方法,或者有更好的替代方法嗎?

回答

0

回答問題1

她建議兩件事情

a)如果您使用的是將來與阻塞調用,然後使用scala.concurrent.blockingblocking告訴默認的執行上下文來產生臨時線程來停止飢餓。可以說blockingServe()確實阻塞。要做多個blockingServe我們使用期貨。

Future { 
    blockingServe() //blockingServe() could be serverSocket.accept() 
} 

但上面的代碼導致了在偶數模型中的飢餓。爲了對付飢餓。我們必須要求執行上下文來創建新的臨時線程來提供額外的請求。這是使用scala.concurrent.blocking

Future { 
    blocking { 
    blockingServe() //blockingServe() could be serverSocket.accept() 
    } 
} 

B)

我們還沒有實現無阻塞仍然傳達給執行上下文。代碼仍然阻塞,但在不同線程中阻塞(異步)

我們如何才能實現真正的非阻塞?

我們可以使用non-blocking api來實現真正的無阻塞。

所以,在你的情況下,你必須使用java.nio.channels.ServerSocketChannel去真正的非阻塞模型。在你的代碼

通知片斷已混合)和b)這並不需要

回答問題2

val selector = Selector.open() 
val serverChannel = ServerSocketChannel.open() 
serverChannel.configureBlocking(false) 
serverChannel.socket().bind(new InetSocketAddress("192.168.2.1", 5000)) 
serverChannel.register(selector, SelectionKey.OP_ACCEPT) 
def assignWork[A](serverChannel: ServerSocketChannel, selector: Selector, work: => Future[A]) = { 

    work 
    //recurse 
} 
assignWork[Unit](serverChannel, selector, Future(())) 
} 
+0

現在我知道了。我感到困惑的是'non-blocking'和'asynchronous'之間的區別。然而,在閱讀了一些輪詢代碼之後,我改變了主意。即使消耗更多的線程,我也會選擇簡單代碼的異步方式。在這種情況下,我的僞代碼是最好的嗎? – dohki

+0

@illuxic是的。你可以去'nio'庫的阻塞版本 – pamu

+0

@illuxic我認爲你的代碼完成了這項工作 – pamu