एक सीधा, लेकिन बिल्कुल सही नहीं है, इस समस्या का हल एक प्रसंस्करण धागे की संख्या के बराबर एक सरणी में उप कतारों का एक सेट बनाए रखना है। एक एकल मास्टर थ्रेड आपके एकल मुख्य कतार से वस्तुओं को खींचता है और उन्हें ऑब्जेक्ट कुंजी के हैशकोड के मॉड्यूलो के माध्यम से अनुक्रमित उप कतार में जोड़ता है (जो भी आपके कार्यों को पहचानता है और उससे संबंधित है)।
उदा।
int queueIndex = myEntity.getKey().hashCode() % queues.length;
केवल एक धागा प्रक्रियाओं है कि कतार, और एक ही इकाई के लिए सभी कार्य है कि कतार में प्रस्तुत किया जाएगा, इसलिए कोई दौड़ की स्थिति हो जाएगा।
यह समाधान अपूर्ण है क्योंकि कुछ धागे दूसरों की तुलना में बड़ी कतारों के साथ समाप्त हो सकते हैं। व्यावहारिक रूप से, यह मामला असंभव है लेकिन यह विचार करने के लिए कुछ है। सरल समाधान के साथ
मुद्दे:
एक भी कतार के बंद आइटम खींच रहा है और उसके बाद प्रभावित इकाई के लिए कुछ अलग पर ताला लगा के सरल समाधान एक रेस स्थिति है (जैसा कि Aurand ने बताया)।यह देखते हुए:
Master Queue [ Task1(entity1), Task2(entity1), ... ]
कहाँ task1
और task2
दोनों एक ही इकाई entity1
संपादित करें, और thread1
और thread2
कतार पर काम है, तो उम्मीद/घटनाओं की वांछित अनुक्रम है है:
- Thread1 task1 लेता है
- ENTITY1 पर Thread1 ताले
- Thread1 संपादित करता ENTITY1
- गु read1 ENTITY1 बातें बताता है
- Thread2 task2
- Thread2 ताले ENTITY1
- Thread2 संपादित करता है लेता है ENTITY1
- Thread2 ENTITY1 बातें बताता है
दुर्भाग्य से, भले ही ताला थ्रेड रन विधि के पहले बयान है, यह निम्नलिखित अनुक्रम के लिए संभव है:
- थ्रेड 1 कार्य 1
- Thread2 task2
- Thread2 ताले ENTITY1
- Thread2 संपादित करता है लेता है ENTITY1
- Thread2 ENTITY1
- Thread1 ताले ENTITY1
- Thread1 संपादित करता बातें बताता है ENTITY1
- Thread1 बातें बताता है ENTITY1
इससे बचने के लिए , प्रत्येक थ्रेड को कतार से कार्य करने से पहले कुछ (कतार कहें) को लॉक करना होगा, ए डी फिर भी पैरेंट लॉक रखने के दौरान इकाई पर एक ताला हासिल करें। हालांकि, आप इस पैरेंट लॉक को पकड़ते हुए और इकाई लॉक प्राप्त करने के लिए प्रतीक्षा करते समय सबकुछ अवरुद्ध नहीं करना चाहते हैं, इसलिए आपको केवल इकाई लॉक के लिए प्रयास करने की आवश्यकता है और फिर जब इसे प्राप्त करने में विफल रहता है तो उसे संभालें (इसे किसी अन्य कतार में रखें) । कुल मिलाकर स्थिति गैर-तुच्छ हो जाती है।
स्रोत
2013-08-21 17:07:05
मुझे लगता है कि अगर आप समझने में आसान बनाने के लिए कुछ छद्म कोड डालते हैं तो यह बेहतर होगा। लेकिन, क्या यह एक संभावना है ?: प्रति व्यक्ति एक निष्पादक की तरह कई निष्पादकों का उपयोग करने के लिए। मैंने कहा कि 'जो' –
के लिए अद्यतन के साथ जेन आउट-ऑफ-ऑर्डर के लिए अद्यतन लागू करना सुरक्षित है नोट करें कि रननेबल के अंदर नाम पर सिंक्रनाइज़ करने से क्रमिक निष्पादन की गारंटी नहीं मिलेगी। एक निष्पादक यह वादा नहीं करता है कि जमा करने के क्रम में कार्य निष्पादित किए जाएंगे (जब तक कि निष्पादक एकल धागा न हो)। – Aurand
@ जोस रेनाटो: मैं प्रति नाम एक थ्रेड का उपयोग करूंगा, नीचे मेरा जवाब देखें। प्रत्येक धागा आदेश स्थिरता सुनिश्चित करता है। –