سؤال

أنا محاولة لاستكشاف متقطع الفشل الذي يظهر أن تكون ذات صلة إلى إزالة كائن من HashMap ثم وضع هذا الكائن نفسه مرة أخرى باستخدام مفتاح جديد.بلدي HashMap يتم إنشاؤه على النحو التالي:

transactions = new HashMap<Short, TransactionBase>();

التعليمات البرمجية التي يعاد التعيين على النحو التالي:

transactions.remove(transaction.tran_no);
transaction.tran_no = generate_transaction_id();
transactions.put(transaction.tran_no, transaction);

متقطعة السلوك الذي أراه هو أن التعليمات البرمجية التي تنفذ على الفور بعد هذا أن يعتمد على الصفقة كائن locatable لا يبدو أن العثور على الكائن الصفقة الجديدة رقم المعاملات.ومع ذلك ، في بعض نقطة في المستقبل ، فإن الصفقة يمكن أن يكون موجودا.حتى سحب بقشة, هل هناك أي نوع من غير متزامن تأثير ضع() أو إزالة التي يمكن أن تسبب هذا النوع من السلوك ؟

أود أن أذكر أن علمي الحاوية يتم الوصول إليها من قبل مؤشر ترابط واحد فقط.سبق لي قراءة في وثائق تلك الفئة HashMap ليست "متزامنة".

هل كانت مفيدة؟

المحلول

ولا توجد آثار "متزامنة" في فئة HashMap. بمجرد وضع شيء في هناك، انها هناك. يجب عليك المزدوج وtriple- تحقق للتأكد من أنه لا توجد قضايا الترابط.

وأما الشيء الوحيد الذي يمكنني أن أفكر فيه هو أن كنت صنع نسخة من HashMap في مكان ما. نسخة من الواضح أن لا تتأثر من إضافة الاشياء في النص الأصلي، أو العكس بالعكس.

نصائح أخرى

وهناك فرق طفيف بين إزالة / الحصول على وضعها (على الرغم من تخميني هو أن لديك مشكلة خيوط).

والمعلمة لremove / get من نوع Object. لput هو من نوع K. وقد ذكر سبب ذلك مرات عديدة من قبل. وهذا يعني انه لديه مشاكل مع الملاكمة. أنا لست حتى الذهاب الى تخمين ما هي القواعد. إذا كان يحصل محاصر قيمة باعتباره Byte في مكان واحد وShort في بلد آخر، ثم تلك الكائنين لا يمكن أن يكون على قدم المساواة.

وهناك مشكلة مشابهة مع List.remove(int) وList.remove(Object).

وأفترض أنه في كل مرة عليك التحقق من وجود هذا البند كنت بالتأكيد باستخدام short أو Short argument إلى Map.get() أو Map.contains()؟

وهذه الأساليب تأخذ الحجج كائن حتى إذا كنت تمر لهم int سيتم تحويلها إلى Integer ولن تطابق أي بند في خريطة لأنهم سوف جميعا Short المفاتيح.

مجرد اقتراح واحد ... كنت تركز على يصل إلى HashMap ولكني أتساءل عما إذا كان يجب عليك أيضا معرفة ما إذا كان generate_transaction_id الخاص بك () هو موضوع آمنة أو إذا كان يتصرف بطريقة غير متوقعة.

هل equals() يتم تجاوز ولكن ليس hashCode() في كائنات النموذج الخاص بك؟ ماذا عن compareTo()؟ إذا كنت تحصل على هذه خاطئة، ومجموعات تتصرف بشكل غريب حقا.

وتحقق الممارسات جافا على () و <أ href ل = "http://www.javapractices.com/topic/TopicAction.do؟Id=10" يختلط = "نوفولو noreferrer"> compareTo () .

وماذا يعني هذا generate_transaction_id وظيفة () القيام به؟ إذا كان توليد 16 بت GUID مثل شيء، هل يمكن بسهولة الحصول على اصطدام التجزئة. جنبا إلى جنب مع خيوط، يمكن أن تحصل:

T1: transaction1.tran_no = generate_transaction_id();    => 1729
T2: transaction2.tran_no = generate_transaction_id();    => 1729
T1: transactions.put(transaction1.tran_no, transaction1); => map.put(1729, transaction1)
T2: transactions.put(transaction2.tran_no, transaction2); => map.put(1729, transaction2)
T1: int tran_no = transactions.get(1729);               => transaction2
T1: transactions.remove(transaction.tran_no);           => map.remove(1729)
T2: int tran_no = transactions.get(1729);               => null

وبطبيعة الحال، هذا يمكن أن يكون إلا حلا اذا كان هذا لأفضل لعلمك "جزء غير صحيح.

وحتى تعرف HashMap ليست ذات ألوان. هل أنت متأكد من انه يتم الوصول إليها عن طريق مؤشر واحد فقط؟ بعد كل شيء، فشل متقطعة وكثيرا خيوط ذات الصلة. إذا لم يكن كذلك، يمكنك ألفه مع <لأ href = "http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collections.html#synchronizedMap(java.util.Map)" يختلط = "نوفولو noreferrer"> Collections.synchronizedMap() ، كما يلي:

Collections.synchronizedMap(transactions);

هل يمكن دائما مجرد محاولة حتى تتمكن من القضاء على هذا الاحتمال.

وتجدر الإشارة إلى أن هذا يلتف مجرد خريطة الأصلي مع واحد مع جميع وسائل متزامنة. قد ترغب في النظر في استخدام كتلة متزامنة إذا تم المترجمة الوصول.

تم ذكر الخيوط في عدد قليل من الردود بالفعل، ولكن هل تعتبر مسألة الرؤية للكائنات التي يستخدمها مواضيع متعددة؟ فمن الممكن (وشائع جدا) أنه إذا وضع الكائن في مجموعة في موضوع واحد، فإنه لن يتم "نشر" إلى المواضيع الأخرى ما لم تقم متزامنة بشكل صحيح على المجموعة.

المواضيع وأقفال

التزامن والسلامة موضوع في جاوة

كما وأشار آخرون عليك أن تعرف ما إذا كان HashMap يتم الوصول إليها من قبل فقط موضوع واحد أو لا. CollectionSpy هو التعريف الذي يتيح لك معرفة على الفور جميع الحاويات ، كيف العديد من المواضيع أداء أي يدخل.انظر www.collectionspy.com للحصول على مزيد من التفاصيل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top