কেন কনক্র্যান্টহ্যাশম্যাপ নাল কী এবং মানগুলি প্রতিরোধ করে?


141

জাভাডক এটি ConcurrentHashMapবলে:

পছন্দ Hashtableতবে অসদৃশ HashMap, এই শ্রেণিটি কী বা মান হিসাবে ব্যবহার করার অনুমতি দেয় নাnull

আমার প্রশ্ন: কেন?

২ য় প্রশ্ন: কেন নালার Hashtableঅনুমতি দেয় না ?

ডেটা সংরক্ষণের জন্য আমি প্রচুর হ্যাশম্যাপ ব্যবহার করেছি। তবে পরিবর্তনের সময় ConcurrentHashMapআমি নুলপয়েন্টারএক্সেপ্সেশনগুলির কারণে বেশ কয়েকবার সমস্যায় পড়েছিলাম।


1
আমি মনে করি এটি একটি চরম বিরক্তিকর অসঙ্গতি। এনামম্যাপটি নালাকেও অনুমতি দেয় না। স্পষ্টত এমন কোনও প্রযুক্তিগত সীমাবদ্ধতা নেই যা নাল কীগুলি অস্বীকার করে। মানচিত্রের জন্য <কে, ভি>, কেবল একটি ভি-টাইপ করা ক্ষেত্র নাল কীগুলির জন্য সহায়তা সরবরাহ করবে (আপনি যদি নাল মান এবং কোনও মানের মধ্যে পার্থক্য করতে চান তবে সম্ভবত অন্য কোনও বুলিয়ান ক্ষেত্র)।
রে

6
একটি আরও ভাল প্রশ্ন "হ্যাশম্যাপ কেন নাল কী এবং নাল মানকে অনুমতি দেয়?" অথবা সম্ভবত, "কেন জাভা নালকে সব ধরণের বাস করতে দেয়?", এমনকি "জাভাতে কেন নাল থাকে?"।
জেড ওয়েসলি-স্মিথ

উত্তর:


220

ConcurrentHashMapনিজের লেখকের কাছ থেকে (ডগ লিয়া) :

কনক্র্যান্টম্যাপস (কনকন্টারিহ্যাশম্যাপস, কনকেন্টারসকিপলিস্টম্যাপস) -এ নালদের অনুমতি না দেওয়ার মূল কারণ হ'ল অস্পষ্টতাগুলি যা সামঞ্জস্যহীন মানচিত্রে সবেমাত্র সহনীয় হতে পারে তা সংযুক্ত করা যায় না। map.get(key)প্রধানটি হ'ল যদি ফেরত আসে তবে nullআপনি সনাক্ত করতে পারবেন না যে কীটি স্পষ্টভাবে nullবনাম কীতে ম্যাপ করা হয়েছে কিনা । অবিচ্ছিন্ন মানচিত্রে, আপনি এটি মাধ্যমে এটি পরীক্ষা করতে পারেন map.contains(key), তবে একযোগে একটিতে মানচিত্র কলগুলির মধ্যে পরিবর্তিত হতে পারে।


7
আপনাকে ধন্যবাদ, কিন্তু কী হিসাবে শূন্যতা সম্পর্কে?
অমিতডাব্লু

2
কেন ব্যবহার করবেন Optionalঅভ্যন্তরীণভাবে মান হিসাবে গুলি
benez

2
@ বেনেজ Optionalএকটি জাভা 8 বৈশিষ্ট্য, যা তখন আর পাওয়া যায় নি (জাভা 5)। আপনি Optionalএখন সত্যিই ব্যবহার করতে পারেন ।
ব্রুনো

@ অমিতডাব্লু, আমি মনে করি যে উত্তরগুলি একই, অস্পষ্টতা। উদাহরণস্বরূপ ধরুন একটি থ্রেড নাল হিসাবে একটি কী তৈরি করে এবং এর বিপরীতে একটি মান সঞ্চয় করে। তারপরে অন্য থ্রেডে অন্য কীটি নালিতে পরিবর্তন করা হয়েছে। যখন দ্বিতীয় থ্রেড নতুন মান যুক্ত করার চেষ্টা করে, এটি প্রতিস্থাপন করা হবে। যদি দ্বিতীয় থ্রেডটি মান পেতে চেষ্টা করে তবে এটি একটি আলাদা কী এর মান পাবে, এটি প্রথম এক দ্বারা পরিবর্তিত। এ জাতীয় পরিস্থিতি এড়ানো উচিত।
ডেক্সটার

44

আমি বিশ্বাস করি যে এটি অন্ততপক্ষে আপনাকে একত্রিত করার containsKeyএবং getএকক কল করার অনুমতি দেবে । মানচিত্রটি যদি নালগুলি ধরে রাখতে পারে তবে তা বলার উপায় নেইget মূল্য নেই যে কোনও নাল ফিরিয়ে দিচ্ছে কারণ সেই মানটির কোনও চাবি ছিল না, বা কেবল মানটি শূন্য ছিল।

কেন যে সমস্যা? কারণ এটি করার কোনও নিরাপদ উপায় নেই। নিম্নলিখিত কোড নিন:

if (m.containsKey(k)) {
   return m.get(k);
} else {
   throw new KeyNotPresentException();
}

যেহেতু mসমবর্তী মানচিত্র, তাই কে containsKeyএবং getকলগুলির মধ্যে মুছে ফেলা হতে পারে , যার ফলে এই স্নিপেটটি কাঙ্ক্ষিতের চেয়ে টেবিলের মধ্যে কখনই ছিল না এমন শূন্যতা ফিরিয়ে আনতে পারে KeyNotPresentException

সাধারণত আপনি এটি সিঙ্ক্রোনাইজ করে সমাধান করে দিতেন তবে একসাথে মানচিত্রের সাহায্যে অবশ্যই কাজ করবে না। সুতরাং এর জন্য স্বাক্ষরটি getবদলাতে হয়েছিল, এবং পিছনের দিকে সামঞ্জস্যপূর্ণ উপায়ে এটি করার একমাত্র উপায় ছিল ব্যবহারকারী প্রথমে নাল মান সন্নিবেশ করানো এবং "কী খুঁজে পাওয়া যায়নি" এর স্থানধারক হিসাবে এটি ব্যবহার চালিয়ে যাওয়া।


আপনি করতে পারেন map.getOrDefault(key, NULL_MARKER)। যদি এটি হয় null, মান ছিল null। যদি এটি ফিরে আসে NULL_MARKERতবে মানটি উপস্থিত ছিল না।
অলিভ

অলিভটি কেবল জাভা ৮-এর মতোই Also
অ্যালিস পুরসেল

@ অ্যালিস্পুরসেল, "তবে একযোগে মানচিত্রের সাহায্যে অবশ্যই এটি কাজ করবে না" - কেন, আমি একইভাবে সমবর্তী সংস্করণে সিঙ্ক্রোনাইজ করতে পারি - কেন এটি কার্যকর হবে না তা ভাবছেন। আপনি এই বিস্তারিত বলতে পারেন
সমাদর

@ সমশার্স সাম্প্রতিক মানচিত্রে কোনও ক্রিয়াকলাপ সিঙ্ক্রোনাইজ করার প্রয়োজন নেই, সুতরাং আপনাকে সমস্ত কলকে বাহ্যিকভাবে সিঙ্ক্রোনাইজ করতে হবে, যেখানে আপনি কেবল একই সময়ের মানচিত্রের সমস্ত কর্মক্ষমতা সুবিধা হ'ল না, আপনি ভবিষ্যতের রক্ষণাবেক্ষণকারীদের জন্য একটি ফাঁদ ফেলে রেখেছেন who প্রাকৃতিকভাবে সিঙ্ক্রোনাইজ না করে নিরাপদে সমবর্তী মানচিত্রে অ্যাক্সেস করতে সক্ষম হওয়া আশা করবে।
এলিস পুরসেল

অ্যালিসপুরসেল, দুর্দান্ত যদিও প্রযুক্তিগতভাবে সম্ভব, এটি অবশ্যই একটি রক্ষণাবেক্ষণের দুঃস্বপ্ন হতে চলেছে এবং পরবর্তী যুগের ব্যবহারকারীদের দ্বারা তারা সমবর্তী সংস্করণে সিঙ্ক করতে হবে বলে আশা করা যায় না।
samshers

4

জোশ ব্লচ ডিজাইন করেছেন HashMap; ডগ লিয়ার নকশা করা হয়েছে ConcurrentHashMap। আমি আশা করি যে এটি মিথ্যা নয়। আসলে আমি মনে করি সমস্যাটি হ'ল নালগুলি প্রায়শই মোড়ানোর প্রয়োজন হয় যাতে প্রকৃত নালটি অনির্বাচিত হয়ে দাঁড়াতে পারে। যদি ক্লায়েন্ট কোডের নালগুলির প্রয়োজন হয় তবে এটি নলগুলি মোড়ানোর জন্য (স্বীকৃতভাবে ছোট) মূল্য দিতে পারে।


2

আপনি একটি নাল সিঙ্ক্রোনাইজ করতে পারবেন না।

সম্পাদনা: এক্ষেত্রে ঠিক এ কারণেই নয়। আমি প্রথমে ভেবেছিলাম সাম্প্রতিক আপডেটগুলির বিরুদ্ধে জিনিসগুলি লক করাতে বা অন্যথায় কিছু পরিবর্তন করা হয়েছে কিনা তা সনাক্ত করতে অবজেক্ট মনিটর ব্যবহার করে অভিনবতা চলছে but তবে উত্স কোডটি পরীক্ষা করার পরে মনে হয় আমি ভুল ছিল - তারা একটি "বিভাগ" ব্যবহার করে লক করেছে হ্যাশ এর বিটমাস্ক।

সেক্ষেত্রে আমার সন্দেহ হয় তারা হ্যাশটেবল অনুলিপি করার জন্য এটি করেছিল, এবং আমি সন্দেহ করি হ্যাশটবেল এটি করেছিলেন কারণ সম্পর্কিত সম্পর্কিত ডাটাবেস ওয়ার্ল্ডে নাল! = নাল, সুতরাং একটি নালকে কী হিসাবে ব্যবহার করার কোনও অর্থ নেই।


তাই না? মানচিত্রের কী এবং মানগুলিতে কোনও সিঙ্ক্রোনাইজেশন করা হয়নি। যে কোন মানে হবে।
টোবিয়াস মুলার

অন্যান্য ধরণের লকিং সম্পন্ন হয়েছে। এটাই এটিকে "সমবর্তী" করে তোলে। এটি করার জন্য, এটি আটকে থাকার জন্য একটি অবজেক্টের প্রয়োজন।
পল টমবলিন

2
কেন অভ্যন্তরীণভাবে কোনও বিশেষ অবজেক্ট নেই যা নাল মানগুলি সিঙ্ক্রোনাইজ করার জন্য ব্যবহার করা যেতে পারে? যেমন "ব্যক্তিগত অবজেক্ট NULL = নতুন অবজেক্ট ();"। আমার মনে হয় আমি এটি আগে দেখেছি ...
মার্সেল

আপনার অন্য কোন ধরণের লকিংয়ের অর্থ কী?
টোবিয়াস মুলার

আসলে, এখন যেহেতু আমি সোর্স কোডটি দেখছি gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/… আমার সে সম্পর্কে গুরুতর সন্দেহ হচ্ছে। এটি পৃথক আইটেমগুলিতে লক না করে সেগমেন্ট লকিং ব্যবহার করে appears
পল টমলিন

0

সমবর্তী হ্যাশম্যাপ থ্রেড-নিরাপদ। আমি বিশ্বাস করি যে নাল কী এবং মানগুলিকে অনুমতি না দেওয়া এটি থ্রেড-নিরাপদ কিনা তা নিশ্চিত করার একটি অংশ ছিল।


0

আমার অনুমান যে এপিআই ডকুমেন্টেশনের নীচের স্নিপেটটি একটি ভাল ইঙ্গিত দেয়: "এই ক্লাসটি হ্যাশটেবলের সাথে পুরোপুরি আন্তঃক্রিয়াযোগ্য যে প্রোগ্রামগুলিতে তার থ্রেড সুরক্ষার উপর নির্ভর করে তবে এটির সিঙ্ক্রোনাইজেশন বিশদ নয়" "

তারা সম্ভবত ConcurrentHashMapসম্পূর্ণরূপে সামঞ্জস্যপূর্ণ / বিনিময়যোগ্য করতে চেয়েছিল Hashtable। এবং যেমন Hashtableনাল কী এবং মানগুলিকে অনুমতি দেয় না ..


2
এবং কেন হ্যাশটেবল সমর্থন বাতিল?
মার্সেল

এর কোডটি অনুসন্ধান করা থেকে, কেন হ্যাশটেবল নাল মানগুলিকে অনুমতি দেয় না তার একটি সুস্পষ্ট কারণ আমি দেখতে পাচ্ছি না। ক্লাসটি তৈরি হওয়ার পরে এটি কেবল পিছনের দিক থেকে একটি এপিআই সিদ্ধান্ত ছিল ?! অভ্যন্তরীণভাবে নাল-কেসের জন্য হ্যাশম্যাপের কিছু বিশেষ হ্যান্ডলিং রয়েছে যা হ্যাশটেবল তা নয়। (এটি সর্বদা নালপয়েন্টার এক্সসেপশনটি ছুড়ে ফেলে))
টোবিয়াস মুলার

-2

আমি মনে করি নাল মান বাতিল করা একটি সঠিক বিকল্প। অনেক ক্ষেত্রে, আমরা কন-বর্তমান মানচিত্রে নাল মান সহ একটি কী রাখতে চাই না। যাইহোক, কনকন্টারহ্যাশম্যাপ ব্যবহার করে আমরা এটি করতে পারি না। আমি পরামর্শ দিচ্ছি যে জেডিকের আসন্ন সংস্করণ এটি সমর্থন করতে পারে।


1
জাভাচ্যাম্পিয়নদের হয়ে প্রতিযোগিতা করার কথা ভেবে দেখেছেন?
ব্ল্যাকবিশপ

আপনি যদি আপনার কীগুলিতে নাল-জাতীয় আচরণ চান তবে ptionচ্ছিক ব্যবহার করুন।
এলিস পুরসেল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.