जावा में, कोई एक बहु-थ्रेडेड वातावरण में आवश्यक संसाधनों तक पहुंचने वाले विधियों या ब्लॉक को सिंक्रनाइज़ करेगा।स्कैला कलाकारों में साझा संसाधन तक पहुंचने का उचित तरीका
मैं सोच रहा हूं कि ऐसा करने का "स्कैला अभिनेता" तरीका कैसे काम करेगा।
मान लीजिए कि मेरे पास java.sql.Connection
ऑब्जेक्ट्स का कनेक्शन पूल है जो मैं थ्रेड-सुरक्षित पहुंच प्रदान करना चाहता हूं। मैं इसे एक अभिनेता के रूप में कार्यान्वित करता हूं जो संदेश प्राप्त करता है और प्रेषक को एक कनेक्शन वापस भेजता है।
यह वहाँ तीन तरीके यह करने के लिए लगता है:
- उपयोग एक भविष्य
- उपयोग
!?
- वर्ग की आवश्यकता होगी,
Connection
भी एक अभिनेता
कोड होना है:
sealed abstract class ConnectionPoolMessage
case class NewConnection extends ConnectionPoolMessage
case class CloseConnection(c:Connection) extends ConnectionPoolMessage
class ConnectionPool extends Actor {
def act() {
while (true) {
receive() {
case NewConnection => sender ! getConnectionFromPool
case CloseConnection(conn) => returnConnection(conn)
}
}
}
}
// Here, my "do stuff" method is all in one place, and I block waiting
// on the Future from the pool; however this could take forever and cause trouble
class UsingFuture {
val pool = new ConnectionPool
def doSomething() {
val connectionFuture = pool !! NewConnection
val connection = connectionFuture() // concerned that we can't timeout here
// do stuff with my Connection instance
pool ! CloseConnection(connection)
}
}
// here, I wait and just use a timeout
// Seems clean to me, I guess.
class UsingBangQuestion {
val pool = new ConnectionPool
def doSomething() {
pool !?(TIMEOUT,NewConnection) match {
case Some(conn) => {
// do something with connection
pool ! CloseConnection(conn)
}
case None => throw new RuntimeException("timed out")
}
}
}
// here, I don't worry about timeouts, cause I only use the
// the connection when I receive a message back with it.
// The problem is that I now have to split my logic up
// with two methods
class AsAnActor extends Actor {
val pool = new ConnectionPool
def startSomething() {
start
pool ! NewConnection
}
def act() {
receive() {
case conn:Connection => finishSomething(conn)
}
}
def finishSomething(conn:Connection) {
// do stuff with my Connection
pool ! CloseConnection(conn)
}
}
भविष्य का संस्करण साफ दिखता है, इस तथ्य को छोड़कर कि मैं हमेशा के लिए ब्लॉक कर सकता हूं।
कोई विचार, या इस गलत की मेरी पूरी धारणा है?
मैं वास्तव में एक कनेक्टेड पूल का उपयोग कर कलाकारों और साझा संसाधनों तक पहुंचने के साधनों के बारे में पूछने के साधन के रूप में उपयोग कर रहा हूं। क्या आप कह रहे हैं कि साझा संसाधनों को साझा संसाधन तक पहुंचने के लिए उपयोग नहीं किया जाना चाहिए? – davetron5000
नहीं - मैं यह बिल्कुल नहीं कह रहा हूं। हालांकि, एक ही कनेक्शन पूल के साथ कई कलाकारों को इंजेक्शन दिया जा सकता है और कनेक्शन प्राप्त करने के लिए उपयुक्त 'सिंक्रनाइज़ेशन' का उपयोग किया जा सकता है। आपके द्वारा वर्णित अन्य विधियों में से कोई भी मान्य है, लेकिन मैं निश्चित रूप से अभिनेताओं पर किसी भी अवरुद्ध कॉल से बचूंगा। –
मुझे लगता है कि मेरा प्रश्न "थ्रेड और सिंक्रनाइज़ेशन कठिन/कठिन/महान नहीं है और यही कारण है कि स्कैला अभिनेता" स्कूल लागू करता है। यानी, मुझे बताया गया है कि स्कैला अभिनेताओं के साथ मिलनसार हल करती है। तो, इस बहुत ही साधारण मामले में, पैटर्न क्या है? तीसरा संस्करण एकमात्र ऐसा है जो अवरुद्ध करने से बचाता है, लेकिन ऐसा लगता है कि मुझे – davetron5000