উদ্বায়ী বুলেটিয়ান বনাম অ্যাটমিকবুলিয়ান


244

অ্যাটমিকবুলিয়ান এমন কী করে যা একটি উদ্বায়ী বুলেটিয়ান অর্জন করতে পারে না?


16
আমি আরও সংক্ষিপ্ত উত্তর খুঁজছিলাম: "প্রত্যেকের সীমাবদ্ধতা কি?" উদাহরণস্বরূপ, যদি কোনও পতাকাটি একটি থ্রেড দ্বারা সেট করা হয় এবং এক বা একাধিক অন্য দ্বারা পড়া হয় তবে অ্যাটমিকবুলিয়ানের প্রয়োজন নেই। যাইহোক, আমি এই উত্তরগুলির সাথে দেখতে পাচ্ছি, যদি থ্রেডটি একাধিক থ্রেডে কোনও চলক ভাগ করে নিচ্ছে এবং তাদের পঠনগুলির ফলাফলের জন্য অভিনয় করতে পারে তবে অ্যাটমিকবুলিয়ান সিএএস টাইপের নন-লকিং অপারেশনটিকে খেলায় নিয়ে আসে। আমি এখানে বেশ কিছুটা শিখছি, আসলে। আশা করি, অন্যরাও উপকৃত হবেন।
জেফভি


অস্থায়ী বুলিয়ান বর্ণের পরিস্থিতি পরিচালনা করতে সুস্পষ্ট সিঙ্ক্রোনাইজেশন প্রয়োজন, অন্য কথায়, ভাগাভাগি সংস্থান যেমন একাধিক থ্রেড দ্বারা আপডেট করা হচ্ছে (রাষ্ট্র পরিবর্তন) যেমন বৃদ্ধি / হ্রাসের পাল্টা বা উল্টানো বুলিয়ান।
sactiw

উত্তর:


99

এরা একেবারেই আলাদা। একটি volatileপূর্ণসংখ্যার উদাহরণটি বিবেচনা করুন :

volatile int i = 0;
void incIBy5() {
    i += 5;
}

দুটি থ্রেড যদি একই সাথে ফাংশনটি কল করে তবে iএটি 5 পরে হতে পারে, যেহেতু সংকলিত কোডটি এর সাথে কিছুটা অনুরূপ হবে (আপনি যদি সিঙ্ক্রোনাইজ করতে না পারেন তবে int):

void incIBy5() {
    int temp;
    synchronized(i) { temp = i }
    synchronized(i) { i = temp + 5 }
}

যদি কোনও পরিবর্তনশীল অস্থির হয় তবে এর প্রতিটি পারমাণবিক অ্যাক্সেস সিঙ্ক্রোনাইজ করা হয় তবে বাস্তবে এটি কী পারমাণবিক অ্যাক্সেস হিসাবে যোগ্যতা অর্জন করে তা সর্বদা স্পষ্ট নয়। একটি Atomic*বস্তুর সাথে, এটি গ্যারান্টিযুক্ত যে প্রতিটি পদ্ধতি "পরমাণু"।

সুতরাং, আপনি যদি একটি AtomicIntegerএবং ব্যবহার করেন getAndAdd(int delta), আপনি নিশ্চিত হতে পারেন যে ফলাফলটি হবে 10। একইভাবে, যদি দুটি থ্রেড উভয়ই booleanএকই সাথে একটি চলককে অস্বীকার করে , একটি দিয়ে AtomicBooleanআপনি নিশ্চিত হতে পারেন যে এটির পরে এর মূল মূল্য আছে তবে volatile booleanআপনি এটি করতে পারবেন না।

সুতরাং যখনই আপনার একটি ক্ষেত্রকে সংশোধন করার একাধিক থ্রেড রয়েছে , আপনার এটিকে অণু তৈরি করতে হবে বা সুস্পষ্ট সিঙ্ক্রোনাইজেশন ব্যবহার করতে হবে।

উদ্দেশ্য volatileএকটি ভিন্ন এক। এই উদাহরণ বিবেচনা করুন

volatile boolean stop = false;
void loop() {
    while (!stop) { ... }
}
void stop() { stop = true; }

আপনার যদি থ্রেড চলমান loop()এবং অন্য থ্রেড কলিং stop()থাকে তবে আপনি বাদ দিলে আপনি একটি অসীম লুপের মধ্যে চলে যেতে পারেন volatile, যেহেতু প্রথম থ্রেড স্টপের মানকে ক্যাশে করতে পারে। এখানে, volatileঅপ্টিমাইজেশানগুলির সাথে কিছুটা সতর্ক হতে সংকলকটির জন্য ইঙ্গিত হিসাবে কাজ করে।


84
-1: আপনি উদাহরণ দিচ্ছেন কিন্তু বাস্তবে একটি অস্থির এবং একটি অ্যাটমিকএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্স।
জেসন এস

70
প্রশ্নটি নিয়ে নয় volatile। প্রশ্ন volatile booleanবনাম সম্পর্কে AtomicBoolean
ডলমেন

26
-১: বুলিয়ান সম্পর্কে বিশেষভাবে জিজ্ঞাসিত প্রশ্নটি, যা অন্যান্য ডেটা ধরণের তুলনায় একটি অনন্য ঘটনা এবং এটি সরাসরি ব্যাখ্যা করা উচিত।
জন হ্যাজার

8
@ এসএজিপি 15 এটি জাভা 5 হিসাবে সিঙ্ক্রোনাইজেশনের সাথে করতে হবে
ম্যান অব ওয়ান ওয়ে

6
বুলিয়ান মানটি যদি অনেক থ্রেড দ্বারা পঠিত হয় তবে কেবল একটি থ্রেড দ্বারা লিখিত হয় তবে volatile booleanতা যথেষ্ট। যদি অনেক লেখক থাকে তবে আপনার প্রয়োজন হতে পারে AtomicBoolean
StvnBrkdll

263

আমি যখন অস্থির ক্ষেত্রগুলি বলি যখন ক্ষেত্রটি কেবল তার মালিকের থ্রেড দ্বারা আপডেট হয় এবং মানটি কেবল অন্য থ্রেড দ্বারা পঠিত হয় তবে আপনি এটিকে একটি প্রকাশ / সাবস্ক্রাইব দৃশ্যে ভাবতে পারেন যেখানে অনেক পর্যবেক্ষক রয়েছে তবে কেবলমাত্র একজন প্রকাশক রয়েছে। তবে যদি সেই পর্যবেক্ষকরা অবশ্যই ক্ষেত্রের মানের ভিত্তিতে কিছু যুক্তি সম্পাদন করতে পারেন এবং তারপরে একটি নতুন মান পিছনে ঠেকান তবে আমি পরমাণু * ওয়ার্স বা লকগুলি বা সিঙ্ক্রোনাইজড ব্লকগুলিতে যাই যা আমার পক্ষে সবচেয়ে উপযুক্ত। অনেক সমসাময়িক পরিস্থিতিতে এটি মান পেতে উত্সাহিত হয়, এটি অন্যটির সাথে তুলনা করুন এবং প্রয়োজনে আপডেট করুন, সুতরাং অ্যাটমিক * শ্রেণিতে উপস্থিত তুলনাআন্ডসেট এবং গেটএন্ডসেট পদ্ধতিগুলি।

পারমাণবিক ক্লাসগুলির একটি তালিকা এবং তারা কীভাবে কাজ করে তার একটি দুর্দান্ত ব্যাখ্যাের জন্য java.util.concurrent.atomic প্যাকেজের জাভাডোকগুলি পরীক্ষা করুন (কেবল শিখেছেন যে তারা লক-মুক্ত রয়েছে, তাই তাদের তালা বা সংক্রামযুক্ত ব্লকের উপর একটি সুবিধা রয়েছে)


1
@ksl আমার মনে হয় @teto বর্ণনা করতে চান যে কেবল একটি থ্রেড যদি ভেরি সংশোধন করে তবে booleanআমাদের বেছে নেওয়া উচিত volatile boolean
znlyj

2
দুর্দান্ত সংক্ষিপ্তসার।
রবীন্দ্র বাবু

56

আপনি ব্যবহার করতে পারবেন না compareAndSet, getAndSetউদ্বায়ী বুলিয়ান সঙ্গে পারমাণবিক অপারেশন হিসাবে (অবশ্যই, যদি না আপনি এটা সুসংগত)।


6
এটি সত্য, তবে এটি কি বুলিয়ানটির জন্য খুব বিরল প্রয়োজন হবে না?
রবিন

1
@ রবিন এটি সূচনা পদ্ধতির অলস প্রার্থনা নিয়ন্ত্রণ করতে এটি ব্যবহার করার বিষয়ে চিন্তা করে।
উস্তামান সংগীত

আসলে আমি মনে করি এটি অন্যতম প্রধান ব্যবহারের ক্ষেত্রে।
বোকা

42

AtomicBooleanএমন পদ্ধতি রয়েছে যা তাদের যৌগিক ক্রিয়াকলাপগুলি পরমাণুভাবে এবং কোনও synchronizedব্লক ব্যবহার না করেই সম্পাদন করে । অন্যদিকে, volatile booleanযদি কোনও synchronizedব্লকের মধ্যে এমনটি করা হয় তবে কেবল যৌগিক ক্রিয়াকলাপ সম্পাদন করতে পারে ।

পড়ার / লেখার স্মৃতি প্রভাবগুলি যথাক্রমে এবং পদ্ধতিগুলির সাথে volatile booleanঅভিন্ন ।getsetAtomicBoolean

উদাহরণস্বরূপ compareAndSetপদ্ধতিটি পরমাণুভাবে নিম্নলিখিতগুলি সম্পাদন করবে (একটি synchronizedব্লক ছাড়াই ):

if (value == expectedValue) {
    value = newValue;
    return true;
} else {
    return false;
}

অতএব, compareAndSetপদ্ধতিটি আপনাকে এমন একাধিক থ্রেড থেকে কল করা হলেও কোডটি লিখতে দেবে যা কেবল একবার কার্যকর করার গ্যারান্টিযুক্ত। উদাহরণ স্বরূপ:

final AtomicBoolean isJobDone = new AtomicBoolean(false);

...

if (isJobDone.compareAndSet(false, true)) {
    listener.notifyJobDone();
}

নিশ্চিত করা হয় শুধুমাত্র এক বার (অন্য কোন থ্রেড সেট অভিমানী শ্রোতা অবহিত AtomicBooleanফিরে falseএটি সেট হওয়ার পর আবার true)।


14

volatileমূলশব্দটি গ্যারান্টি দেয় যে থ্রেডগুলি ভাগ করে নেওয়ার আগে সম্পর্কের আগে সেই পরিবর্তনশীল। এটি আপনাকে গ্যারান্টি দেয় না যে 2 বা ততোধিক থ্রেডগুলি সেই বুলিয়ান ভেরিয়েবলটি অ্যাক্সেস করার সময় একে অপরকে বাধা দেয় না।


14
বুলিয়ান (আদিম ধরণের হিসাবে) অ্যাক্সেস জাভাতে পারমাণবিক। উভয় পড়া এবং অ্যাসাইনমেন্ট। সুতরাং অন্য কোনও থ্রেড বুলেটিয়ান ক্রিয়াকলাপগুলিকে "বাধা" দেবে না।
ম্যাকিয়েজ বায়াস

1
আমি দুঃখিত কিন্তু এই প্রশ্নের উত্তর কিভাবে দেয়? একটি Atomic*শ্রেণি একটি volatileক্ষেত্র জড়ায় ।
ধূসর

অস্থিরতা স্থাপনের মূল কারণ কি সিপিইউ নয়? মূল্য পড়ার বিষয়টি হ'ল এটি কী সাম্প্রতিক সময়ে সেট করা হয়েছিল তা নিশ্চিত করার জন্য
জোকুল

8

উদ্বায়ী বুলেটিয়ান বনাম অ্যাটমিকবুলিয়ান

পারমাণবিক * ক্লাসগুলি একই ধরণের একটি উদ্বায়ী আদিমকে আবদ্ধ করে। উত্স থেকে:

public class AtomicLong extends Number implements java.io.Serializable {
   ...
   private volatile long value;
   ...
   public final long get() {
       return value;
   }
   ...
   public final void set(long newValue) {
       value = newValue;
   }

সুতরাং আপনি যদি যা করছেন তার সবই যদি পারমাণবিক * পেতে এবং সেট করা হয় তবে আপনার পরিবর্তে কেবল একটি অস্থির ক্ষেত্র থাকতে পারে।

অ্যাটমিকবুলিয়ান এমন কী করে যা একটি উদ্বায়ী বুলেটিয়ান অর্জন করতে পারে না?

আণবিক * শ্রেণীর আপনি পদ্ধতি যেমন আরো উন্নত কার্যকারিতা প্রদান দিতে incrementAndGet(), compareAndSet(), এবং অন্যদের যে লকিং ছাড়া একাধিক কার্যকলাপ (পেতে / বৃদ্ধি / সেট, পরীক্ষা / সেট থাকে) বাস্তবায়ন। এ কারণেই পারমাণবিক * শ্রেণিগুলি এত শক্তিশালী।

উদাহরণস্বরূপ, যদি একাধিক থ্রেড নিম্নলিখিত কোডগুলি ব্যবহার করে ব্যবহার করে তবে ++রেসের শর্ত থাকবে কারণ ++বাস্তবে: পান, বৃদ্ধি এবং সেট করুন।

private volatile value;
...
// race conditions here
value++;

তবে, নিম্নলিখিত কোডটি লক ছাড়াই নিরাপদে বহু-থ্রেড পরিবেশে কাজ করবে:

private final AtomicLong value = new AtomicLong();
...
value.incrementAndGet();

এটাও লক্ষ করা জরুরী যে পারমাণবিক * বর্গ ব্যবহার করে আপনার উদ্বায়ী ক্ষেত্রটি মুড়িয়ে ফেলা একটি অবজেক্টের দৃষ্টিকোণ থেকে সমালোচনামূলকভাবে ভাগ করা সংস্থানকে আবদ্ধ করার একটি ভাল উপায়। এর অর্থ হল যে বিকাশকারীরা ক্ষেত্রটি ++ এর সাথে সম্ভবত ইনজেকশনের সমস্যাগুলি সম্ভবত ভাগ করে নেওয়া হচ্ছে তা ধরে নিয়ে ক্ষেত্রটি মোকাবেলা করতে পারবেন না; বা অন্যান্য কোড যা জাতি শর্ত প্রবর্তন করে।


5

যদি শ্রেণি স্তরের ভেরিয়েবল অ্যাক্সেস করে একাধিক থ্রেড থাকে তবে প্রতিটি থ্রেড সেই পরিবর্তনশীলটির অনুলিপিটি তার থ্রডলোকাল ক্যাশে রাখতে পারে।

ভেরিয়েবলটিকে অস্থির করে তুলতে থ্রেডলোকাল ক্যাশে ভেরিয়েবলের অনুলিপি রাখা থ্রেডগুলিকে আটকাবে।

পারমাণবিক পরিবর্তনশীলগুলি পৃথক এবং তারা তাদের মানগুলিতে পারমাণবিক পরিবর্তনের অনুমতি দেয়।


4

বুলিয়ান আদিম প্রকারটি লেখার এবং পড়ার ক্রিয়াকলাপগুলির জন্য পারমাণবিক, অস্থায়ী হওয়ার আগে-নীতিটির গ্যারান্টি দেয়। সুতরাং আপনার যদি সহজ সরল () এবং সেট () সেট করতে হয় তবে আপনার অ্যাটমিকবুলিয়ান লাগবে না।

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


3

IDIOM মনে রাখবেন -

পড়ুন - মোডিফাই করুন - এইটি লিখুন আপনি অস্থিরতার সাথে অর্জন করতে পারবেন না


2
সংক্ষিপ্ত, খাস্তা এবং বিন্দু। volatileকেবলমাত্র সেই ক্ষেত্রে কাজ করে যেখানে মালিকের থ্রেডের ক্ষেত্রে ক্ষেত্রের মান আপডেট করার ক্ষমতা থাকে এবং অন্যান্য থ্রেডগুলি কেবলমাত্র পড়তে পারে।
চাকলাদার আসফাক আরেেফ

3

আপনার বুলিয়ান পরিবর্তন করতে যদি আপনার কাছে কেবল একটি থ্রেড থাকে তবে আপনি একটি অস্থির বুলেটিয়ান ব্যবহার করতে পারেন (সাধারণত আপনি stopথ্রেডের মূল লুপটিতে পরীক্ষা করা একটি ভেরিয়েবল সংজ্ঞায়িত করতে এটি করেন)।

তবে, আপনার যদি বুলিয়ান পরিবর্তন করে একাধিক থ্রেড থাকে, আপনার একটি ব্যবহার করা উচিত AtomicBoolean। অন্যথায়, নিম্নলিখিত কোডটি নিরাপদ নয়:

boolean r = !myVolatileBoolean;

এই অপারেশনটি দুটি পদক্ষেপে করা হয়:

  1. বুলিয়ান মান পড়া হয়।
  2. বুলিয়ান মান লেখা হয়।

একটি অন্য থ্রেডের মধ্যে মান পরিবর্তন যদি #1এবং 2#, আপনি একটি ভুল ফলাফল পেয়েছি পারে। AtomicBooleanপদ্ধতিগুলি পদক্ষেপ #1এবং #2পারমাণবিকভাবে এই সমস্যাটি এড়ায়।


-1

উভয়ই একই ধারণার তবে পারমাণবিক বুলিয়ান এটি সিপিইউ সুইচ এর মধ্যে ঘটতে পারলে এটি অপারেশনে পারমাণবিকতা সরবরাহ করবে।

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