java - পারমাণবিক/অস্থির/সিঙ্ক্রোনাইজড মধ্যে পার্থক্য কি?




multithreading synchronization (5)

আমি জানি যে দুটি থ্রেড একই সময়ে ব্লক সিঙ্ক্রোনাইজ করতে পারবে না

দুটি থ্রেড একই বস্তুতে দুটি বারে একটি সিঙ্ক্রোনাইজড ব্লক প্রবেশ করতে পারে না। এর অর্থ হল দুটি থ্রেড বিভিন্ন বস্তুর একই ব্লকটি প্রবেশ করতে পারে। এই বিভ্রান্তি এই মত কোড হতে পারে।

private Integer i = 0;

synchronized(i) {
   i++;
}

এটি প্রত্যাশিত হিসাবে আচরণ করবে না কারণ এটি প্রতিটি সময় আলাদা আলাদাভাবে লক করা যেতে পারে।

এটি যদি সত্য হয় তবে এই atomic.incrementAndGet () কিভাবে সিঙ্ক্রোনাইজ না করে কাজ করে ?? এবং থ্রেড নিরাপদ ??

হ্যাঁ। এটি থ্রেড নিরাপত্তা অর্জন লকিং ব্যবহার করে না।

আপনি যদি আরও বিস্তারিতভাবে কীভাবে কাজ করেন তা জানতে চান তবে আপনি তাদের জন্য কোডটি পড়তে পারেন।

এবং ভার্চুয়াল ভেরিয়েবল / পরমাণু পরিবর্তনশীল অভ্যন্তরীণ পড়া এবং লেখা মধ্যে পার্থক্য কি ??

পারমাণবিক বর্গ অস্থির ক্ষেত্র ব্যবহার করে। মাঠে কোন পার্থক্য নেই। পার্থক্য অপারেশন সঞ্চালিত হয়। পারমাণবিক ক্লাস তুলনা করুন এবং স্যুইপ বা সিএএস অপারেশন ব্যবহার করুন।

আমি কিছু নিবন্ধে পড়ি যে থ্রেডের ভেরিয়েবলগুলির স্থানীয় কপিটি কী?

আমি কেবলমাত্র এটি অনুমান করতে পারি যে প্রতিটি CPU এ তার নিজস্ব ক্যাশেড ভিউয়ের মেমরি রয়েছে যা প্রতিটি অন্য CPU থেকে আলাদা হতে পারে। আপনার CPU এর ডেটা সামঞ্জস্যপূর্ণ দৃশ্যটি নিশ্চিত করার জন্য আপনাকে থ্রেড সুরক্ষা কৌশলগুলি ব্যবহার করতে হবে।

মেমরি কমপক্ষে একটি থ্রেড আপডেট ভাগ করা হয় যখন এটি শুধুমাত্র একটি সমস্যা।

কিভাবে আণবিক / উদ্বায়ী / অভ্যন্তরীণভাবে সিঙ্ক্রোনাইজ কাজ?

নিম্নলিখিত কোড ব্লক মধ্যে পার্থক্য কি?

কোড 1

private int counter;

public int getNextUniqueIndex() {
    return counter++; 
}

কোড 2

private AtomicInteger counter;

public int getNextUniqueIndex() {
    return counter.getAndIncrement();
}

কোড 3

private volatile int counter;

public int getNextUniqueIndex() {
    return counter++; 
}

নিম্নলিখিত পথে volatile কাজ করে? কি

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

সমতুল্য

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

আমি মনে করি যে দুটি থ্রেড একই সময়ে একটি সিঙ্ক্রোনাইজড ব্লক প্রবেশ করতে পারে না ... আমি কি ঠিক? যদি এটি সত্য হয় তবে কিভাবে atomic.incrementAndGet() synchronized ছাড়া কাজ synchronized ? এবং এটা থ্রেড নিরাপদ?

এবং অভ্যন্তরীণ পড়া এবং অস্থির ভেরিয়েবল / পারমাণবিক ভেরিয়েবল লিখতে পার্থক্য কি? আমি কিছু নিবন্ধে পড়ি যে থ্রেডে ভেরিয়েবলের একটি স্থানীয় অনুলিপি রয়েছে - সেটা কী?


আপনি বিশেষভাবে কিভাবে তারা অভ্যন্তরীণভাবে কাজ সম্পর্কে জিজ্ঞাসা করা হয়, তাই এখানে আপনি আছেন:

কোন সিঙ্ক্রোনাইজেশন

private int counter;

public int getNextUniqueIndex() {
  return counter++; 
}

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

private boolean stopped;

public void run() {
    while(!stopped) {
        //do some work
    }
}

public void pleaseStop() {
    stopped = true;
}

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

AtomicInteger

private AtomicInteger counter = new AtomicInteger();

public int getNextUniqueIndex() {
  return counter.getAndIncrement();
}

AtomicInteger ক্লাসটি সিএএস ( compare-and-swap ) কম-স্তরীয় CPU অপারেশনগুলি ব্যবহার করে (কোনও সিঙ্ক্রোনাইজেশন প্রয়োজন!) তারা যদি কোনও নির্দিষ্ট পরিবর্তনশীলকে কেবলমাত্র পরিবর্তন করতে দেয় তবে বর্তমান মানটি অন্য কোনটির সমান (এবং সফলভাবে ফেরত দেওয়া হয়)। সুতরাং যখন আপনি getAndIncrement() বাস্তবায়িত করেন তখন এটি আসলে একটি লুপে getAndIncrement() (সরলীকৃত বাস্তব বাস্তবায়ন):

int current;
do {
  current = get();
} while(!compareAndSet(current, current + 1));

তাই মূলত: পড়া; বর্ধিত মান সংরক্ষণ করার চেষ্টা করুন; সফল না হলে (মান বর্তমানের সমান নয়), পড়া এবং আবার চেষ্টা করুন। compareAndSet() স্থানীয় কোড (সমাবেশ) প্রয়োগ করা হয়।

সিঙ্ক্রোনাইজেশন ছাড়া volatile

private volatile int counter;

public int getNextUniqueIndex() {
  return counter++; 
}

এই কোড সঠিক নয়। এটি দৃশ্যমানতা সমস্যা স্থির করে ( volatile নিশ্চিত করে যে অন্যান্য থ্রেড counter পরিবর্তিত পরিবর্তন দেখতে পারে) তবে এখনও একটি জাতি শর্ত রয়েছে। এই একাধিক বার explained হয়েছে: প্রাক / পোস্ট বৃদ্ধি বৃদ্ধি পারমাণবিক নয়।

volatile একমাত্র পার্শ্ব প্রতিক্রিয়া হল " ফ্লাশিং " ক্যাশে যাতে সমস্ত অন্যান্য পক্ষগুলি তথ্যটির নতুন সংস্করণটি দেখতে পায়। এই বেশিরভাগ পরিস্থিতিতে খুব কঠোর হয়; যে কারণে volatile ডিফল্ট নয়।

সিঙ্ক্রোনাইজেশন ছাড়া volatile (2)

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

উপরে হিসাবে একই সমস্যা, কিন্তু এমনকি খারাপ কারণ i private নয়। জাতি অবস্থা এখনও উপস্থিত। কেন এটি একটি সমস্যা? যদি বলা হয়, দুটি থ্রেড একযোগে এই কোডটি চালায়, আউটপুট + 5 বা + 10 হতে পারে। তবে, আপনি পরিবর্তন দেখতে নিশ্চিত।

একাধিক স্বাধীন synchronized

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

অবাক, এই কোড পাশাপাশি ভুল। আসলে, এটা সম্পূর্ণ ভুল। প্রথমে i আপনার সাথে সিঙ্ক্রোনাইজ i , যা পরিবর্তিত হবে (আরও, i একটি আদিম, তাই আমি অনুমান করছি যে আপনি অটোমক্সিংয়ের মাধ্যমে তৈরি একটি অস্থায়ী Integer উপর সিঙ্ক্রোনাইজ করছেন ...) সম্পূর্ণরূপে ত্রুটিযুক্ত। আপনিও লিখতে পারেন:

synchronized(new Object()) {
  //thread-safe, SRSLy?
}

কোন লক একই লক দিয়ে একই synchronized ব্লক প্রবেশ করতে পারেন। এই ক্ষেত্রে (এবং অনুরূপভাবে আপনার কোডে) লক অবজেক্টটি প্রতিটি কার্যকরকরণে পরিবর্তিত হয়, তাই synchronized কার্যকরভাবে কোন প্রভাব নেই।

এমনকি যদি আপনি সিঙ্ক্রোনাইজেশনের জন্য একটি চূড়ান্ত পরিবর্তনশীল (বা this ) ব্যবহার করেছেন, তবে কোডটি এখনও ভুল। দুটি থ্রেড প্রথমে i temp ( i একই রূপে স্থানীয়ভাবে একই মান ধারণ করতে) পড়তে পারি, তারপর প্রথমে i একটি নতুন মান নির্ধারণ i (বলে, 1 থেকে 6 পর্যন্ত) এবং অন্যটি একই জিনিস করে (1 থেকে 6 পর্যন্ত) ।

সিঙ্ক্রোনাইজেশন একটি মান বরাদ্দ পড়া থেকে ব্যয় করা আবশ্যক। আপনার প্রথম সিঙ্ক্রোনাইজেশনের কোন প্রভাব নেই (একটি int পড়াটি পারমাণবিক) এবং দ্বিতীয়টিও ভাল। আমার মতে, এই সঠিক ফর্ম:

void synchronized incIBy5() {
  i += 5 
}

void incIBy5() {
  synchronized(this) {
    i += 5 
  }
}

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

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

পারমাণবিক অপারেশন অন্যান্য অপারেশন থেকে হস্তক্ষেপ ছাড়া কাজ একক ইউনিট সঞ্চালিত হয়। তথ্য অসঙ্গতি এড়াতে পারমাণবিক অপারেশন মাল্টি-থ্রেডেড পরিবেশে প্রয়োজনীয়তা।


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

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

পরিবর্তনশীলের সমস্ত অ্যাক্সেস সিঙ্ক্রোনাইজ করার জন্য কেবলমাত্র একক থ্রেডকে পরিবর্তনশীল অ্যাক্সেসের অনুমতি দেয় এবং অন্যান্য সমস্ত থ্রেডকে তার অ্যাক্সেসের জন্য অপেক্ষা করতে থ্রেডের জন্য অপেক্ষা করতে সক্ষম করে।

সমলয় অ্যাক্সেসটি পারমাণবিক অ্যাক্সেসের সমান, তবে পরমাণু ক্রিয়াকলাপগুলি সাধারণত নিম্ন স্তরের প্রোগ্রামিংয়ে প্রয়োগ করা হয়। এছাড়াও, এটি শুধুমাত্র একটি পরিবর্তনশীলের অ্যাক্সেসের জন্য কেবলমাত্র অ্যাক্স্রোনাইজ করা সম্ভব এবং অন্য অ্যাক্সেসগুলিকে অ-সিঙ্ক্রোনাইজড করার অনুমতি দেয় (উদাহরণস্বরূপ, সমস্ত লেখা একটি পরিবর্তনশীলকে সিঙ্ক্রোনাইজ করুন তবে এর থেকে কোনও পাঠ্য নেই)।

পারমাণবিকতা, সিঙ্ক্রোনাইজেশন, এবং উদ্বায়ীতা স্বাধীন বৈশিষ্ট্য, তবে সাধারণত ভেরিয়েবল অ্যাক্সেসের জন্য সঠিক থ্রেড সহযোগিতা প্রয়োগ করার জন্য সমন্বয়ে ব্যবহৃত হয়।

অ্যাডেন্ডাম (এপ্রিল 2016)

একটি পরিবর্তনশীল অ্যাক্সেস সমলয় অ্যাক্সেস সাধারণত একটি মনিটর বা semaphore ব্যবহার করে প্রয়োগ করা হয়। এটি নিম্ন-স্তরের mutex (পারস্পরিক বর্জন) প্রক্রিয়াগুলি যা একটি থ্রেডকে কেবল একটি পরিবর্তনশীল বা কোডের ব্লক নিয়ন্ত্রণে নিয়ন্ত্রণ করার অনুমতি দেয়, অন্য সমস্ত থ্রেডগুলিকে একই মুপেক্সটি অর্জন করার চেষ্টা করার জন্য অপেক্ষা করতে বাধ্য করে। একবার মালিকানাধীন থ্রেডটি মু्यूटক্সটি প্রকাশ করলে, অন্য একটি থ্রেড মু्यूटক্সটি ঘুরিয়ে নিতে পারে।

অ্যাডেন্ডাম (জুলাই 2016)

সিঙ্ক্রোনাইজেশন একটি বস্তুর উপর ঘটে। এর অর্থ হল একটি শ্রেণির একটি সিঙ্ক্রোনাইজড পদ্ধতি কল করা এই কলটির লকটি লক করবে। স্ট্যাটিক সিঙ্ক্রোনাইজড পদ্ধতি Class অবজেক্টটিকে নিজেই লক করে দেবে।

একইভাবে, একটি সিঙ্ক্রোনাইজড ব্লক প্রবেশ করার পদ্ধতিটির this বস্তুর লকিংয়ের প্রয়োজন হয়।

এর মানে হল যে একাধিক থ্রেডগুলিতে একাধিক থ্রেডগুলিতে একক সিঙ্ক্রোনাইজড পদ্ধতি (বা ব্লক) একযোগে নির্বাহ করা যেতে পারে যদি তারা বিভিন্ন বস্তুর উপর লক করা থাকে তবে শুধুমাত্র একটি থ্রেড কোন প্রদত্ত একক বস্তুর জন্য একটি সময়ে সিঙ্ক্রোনাইজড পদ্ধতি (বা ব্লক) চালাতে পারে।


সিঙ্ক্রোনাইজড Vs পরমাণু Vs ভলটাইল:
1. অস্থায়ী এবং পরমাণু শুধুমাত্র পরিবর্তনশীল প্রয়োগ করা হয়, সিঙ্ক্রোনাইজড পদ্ধতিতে প্রয়োগ করা হয়।
2. অস্থিরতা বস্তুর পারমাণবিকতা / সামঞ্জস্যতা দৃশ্যমানতা সম্পর্কে নিশ্চিত, অন্যরা উভয় দৃশ্যমানতা এবং পরমাণু সম্পর্কে নিশ্চিত।
3. RAM এ ভলিয়েল ভেরিয়েবল স্টোর এবং এটি অ্যাক্সেসে দ্রুত তবে আমরা থ্রেড সুরক্ষা বা সিঙ্ক্রোনাইজেশন হোয়াইটআউট সিঙ্ক্রোনাইজড কীওয়ার্ড অ্যাক্টিভ করতে পারছি না।
4. সিঙ্ক্রোনাইজড উভয় সময় সিঙ্ক্রোনাইজড ব্লক বা সিঙ্ক্রোনাইজড পদ্ধতি রূপে প্রয়োগ করা হয়েছে। আমরা থ্রেড নিরাপদ একাধিক লাইন কোডের সাহায্যে সিঙ্ক্রোনাইজড কীওয়ার্ডের সাহায্যে করতে পারি যখন আমরা উভয় একই অর্জন করতে পারি না।
5. সিঙ্ক্রোনাইজ করা একই ক্লাস অবজেক্ট বা বিভিন্ন ক্লাস অবজেক্ট লক করতে পারেন যখন উভয় করতে পারে না।
আমি মিস্ কিছু যদি আমার সংশোধন করুন।







volatile