synchronizedকীওয়ার্ডটির ব্যবহার এবং তাৎপর্য সম্পর্কে আমার কিছু প্রশ্ন রয়েছে ।
synchronizedকীওয়ার্ডটির তাৎপর্য কী ?- পদ্ধতিগুলি কখন হওয়া উচিত
synchronized? - এটি প্রোগ্রামিক এবং যৌক্তিকর অর্থ কী?
synchronizedকীওয়ার্ডটির ব্যবহার এবং তাৎপর্য সম্পর্কে আমার কিছু প্রশ্ন রয়েছে ।
synchronizedকীওয়ার্ডটির তাৎপর্য কী ?synchronized?উত্তর:
মূল synchronizedশব্দটি হ'ল বিভিন্ন থ্রেডগুলি একই ভেরিয়েবল, অবজেক্ট এবং সংস্থানগুলিতে পড়া এবং লেখার বিষয়ে। এটি জাভাতে তুচ্ছ বিষয় নয়, তবে এখানে সূর্যের একটি উদ্ধৃতি দেওয়া হয়েছে:
synchronizedপদ্ধতিগুলি থ্রেড হস্তক্ষেপ এবং মেমরির ধারাবাহিকতা ত্রুটিগুলি রোধ করার জন্য একটি সহজ কৌশল সক্ষম করে: যদি কোনও বস্তু একাধিক থ্রেডের কাছে দৃশ্যমান হয় তবে সেই বস্তুর ভেরিয়েবলগুলিতে সমস্ত পড়তে বা লেখাকে সিঙ্ক্রোনাইজড পদ্ধতির মাধ্যমে করা হয়।
খুব খুব ছোট সংক্ষেপে: যখন আপনার দুটি থ্রেড থাকে যা একই 'রিসোর্স' তে পড়তে এবং লিখতে থাকে, তখন একটি ভেরিয়েবলের নাম বলুন foo, আপনাকে নিশ্চিত করতে হবে যে এই থ্রেডগুলি একটি পারমাণবিক উপায়ে পরিবর্তনশীল অ্যাক্সেস করতে পারে। synchronizedকীওয়ার্ড ব্যতীত , আপনার থ্রেড 1 টি পরিবর্তিত থ্রেড 2 টির পরিবর্তিত থ্রেড দেখতে পাবে না fooবা আরও খারাপ, এটি কেবলমাত্র অর্ধেক পরিবর্তিত হতে পারে। আপনি যৌক্তিকভাবে এটি প্রত্যাশা করবেন না।
আবার এটি জাভাতে একটি তুচ্ছ বিষয়। আরও শিখতে, এখানে এসও এবং ইন্টারভেইবগুলিতে বিষয়গুলি অন্বেষণ করুন:
"ব্রায়ান গোয়েটস" নামটি আপনার মস্তিষ্কে "কনক্যুরঞ্জি" শব্দটির সাথে স্থায়ীভাবে যুক্ত না হওয়া অবধি এই বিষয়গুলি অন্বেষণ করতে থাকুন ।
ঠিক আছে, আমি মনে করি আমাদের তাত্ত্বিক ব্যাখ্যা যথেষ্ট ছিল, তাই এই কোডটি বিবেচনা করুন
public class SOP {
public static void print(String s) {
System.out.println(s+"\n");
}
}
public class TestThread extends Thread {
String name;
TheDemo theDemo;
public TestThread(String name,TheDemo theDemo) {
this.theDemo = theDemo;
this.name = name;
start();
}
@Override
public void run() {
theDemo.test(name);
}
}
public class TheDemo {
public synchronized void test(String name) {
for(int i=0;i<10;i++) {
SOP.print(name + " :: "+i);
try{
Thread.sleep(500);
} catch (Exception e) {
SOP.print(e.getMessage());
}
}
}
public static void main(String[] args) {
TheDemo theDemo = new TheDemo();
new TestThread("THREAD 1",theDemo);
new TestThread("THREAD 2",theDemo);
new TestThread("THREAD 3",theDemo);
}
}
দ্রষ্টব্য: synchronizedপূর্ববর্তী থ্রেডের কার্যকারিতা শেষ না হওয়া অবধি পরবর্তী থ্রেডের কলটি মেথড টেস্টে কল করুন ()। থ্রেডগুলি একবারে এই পদ্ধতিতে অ্যাক্সেস করতে পারে। synchronizedসমস্ত থ্রেড ব্যতীত একই পদ্ধতিতে অ্যাক্সেস করতে পারে।
কোনও থ্রেড যখন বস্তুর সিঙ্ক্রোনাইজড পদ্ধতিটিকে 'পরীক্ষা' বলবে (এখানে বস্তুটি 'থিমডো' শ্রেণীর উদাহরণ) এটি সেই বস্তুর লকটি অর্জন করে, কোনও নতুন থ্রেড পূর্ববর্তী থ্রেডের মতো একই বস্তুর কোনও সিঙ্ক্রোনাইজড পদ্ধতিতে কল করতে পারে না cannot যা লকটি অর্জন করেছিল তা লকটি প্রকাশ করে না।
ক্লাসের যে কোনও স্ট্যাটিক সিঙ্ক্রোনাইজড মেথড বলা হয়ে থাকে তখন একই জিনিস ঘটে। থ্রেডটি শ্রেণীর সাথে সম্পর্কিত লকটি অর্জন করে (এক্ষেত্রে class শ্রেণীর উদাহরণের কোনও অ স্ট্যাটিক সিঙ্ক্রোনাইজড পদ্ধতি কোনও থ্রেড দ্বারা কল করা যেতে পারে কারণ সেই বস্তুর স্তরের লকটি এখনও উপলব্ধ। ক্লাস স্তরের লকটি বর্তমানে থ্রেড দ্বারা প্রকাশিত না করা অবধি ক্লাসের কোনও স্থির সিঙ্ক্রোনাইজড পদ্ধতিতে কল করতে সক্ষম হবে না যতক্ষণ না বর্তমানে তালা ধরে আছে।
সিঙ্ক্রোনাইজড আউটপুট
THREAD 1 :: 0
THREAD 1 :: 1
THREAD 1 :: 2
THREAD 1 :: 3
THREAD 1 :: 4
THREAD 1 :: 5
THREAD 1 :: 6
THREAD 1 :: 7
THREAD 1 :: 8
THREAD 1 :: 9
THREAD 3 :: 0
THREAD 3 :: 1
THREAD 3 :: 2
THREAD 3 :: 3
THREAD 3 :: 4
THREAD 3 :: 5
THREAD 3 :: 6
THREAD 3 :: 7
THREAD 3 :: 8
THREAD 3 :: 9
THREAD 2 :: 0
THREAD 2 :: 1
THREAD 2 :: 2
THREAD 2 :: 3
THREAD 2 :: 4
THREAD 2 :: 5
THREAD 2 :: 6
THREAD 2 :: 7
THREAD 2 :: 8
THREAD 2 :: 9
সিঙ্ক্রোনাইজড ছাড়া আউটপুট
THREAD 1 :: 0
THREAD 2 :: 0
THREAD 3 :: 0
THREAD 1 :: 1
THREAD 2 :: 1
THREAD 3 :: 1
THREAD 1 :: 2
THREAD 2 :: 2
THREAD 3 :: 2
THREAD 1 :: 3
THREAD 2 :: 3
THREAD 3 :: 3
THREAD 1 :: 4
THREAD 2 :: 4
THREAD 3 :: 4
THREAD 1 :: 5
THREAD 2 :: 5
THREAD 3 :: 5
THREAD 1 :: 6
THREAD 2 :: 6
THREAD 3 :: 6
THREAD 1 :: 7
THREAD 2 :: 7
THREAD 3 :: 7
THREAD 1 :: 8
THREAD 2 :: 8
THREAD 3 :: 8
THREAD 1 :: 9
THREAD 2 :: 9
THREAD 3 :: 9
synchronizedতবে মেমরির ধারাবাহিকতা উপেক্ষা করা হয়।
synchronizedশব্দ একাধিক থ্রেড দ্বারা কোড বা বস্তুর একটি ব্লক জন্য সংঘটনশীল এক্সেস বাধা দেয়। সকল পদ্ধতি Hashtableরয়েছে synchronized, তাই শুধুমাত্র একটি থ্রেড একটি সময়ে তাদের কোন নির্বাহ করতে পারেন।
অ- synchronizedনির্মাণের মতো ব্যবহার করার সময় HashMap, ধারাবাহিকতা ত্রুটিগুলি রোধ করতে আপনাকে অবশ্যই আপনার কোডে থ্রেড-সুরক্ষা বৈশিষ্ট্য তৈরি করতে হবে।
synchronizedএর অর্থ হ'ল একাধিক থ্রেড পরিবেশে কোনও synchronizedপদ্ধতি (গুলি) / ব্লক (গুলি) থাকা দুটি বস্তু synchronizedএকই সাথে কোডের পদ্ধতি (গুলি) / ব্লক (গুলি) অ্যাক্সেস করতে দেয় না । এর অর্থ হ'ল একটি থ্রেড পড়তে পারে না যখন অন্য থ্রেড এটি আপডেট করে।
দ্বিতীয় থ্রেড পরিবর্তে প্রথম থ্রেডটির সম্পাদন শেষ হওয়া পর্যন্ত অপেক্ষা করবে। ওভারহেড গতিযুক্ত, তবে সুবিধাটি ডেটাটির ধারাবাহিকতার গ্যারান্টিযুক্ত।
আপনার অ্যাপ্লিকেশনটি যদিও একক থ্রেডযুক্ত তবে synchronizedব্লকগুলি কোনও সুবিধা দেয় না।
synchronizedশব্দ যখন পদ্ধতি লিখে একটি লক প্রাপ্ত, যাতে শুধুমাত্র এক থ্রেড একই সময়ে পদ্ধতি নির্বাহ করতে পারেন (প্রদত্ত বস্তু উদাহরণস্বরূপ, যদি না তা একটি স্ট্যাটিক পদ্ধতি) একটি থ্রেড ঘটায়।
একে প্রায়শই ক্লাসের থ্রেড-নিরাপদ তৈরি বলা হয়, তবে আমি বলব এটি একটি শ্রুতিমধুরতা। যদিও এটি সত্য যে সিঙ্ক্রোনাইজেশন ভেক্টরের অভ্যন্তরীণ অবস্থাটিকে দূষিত হওয়ার হাত থেকে রক্ষা করে, এটি সাধারণত ভেক্টরের ব্যবহারকারীর পক্ষে খুব বেশি সহায়তা করে না।
এই বিবেচনা:
if (vector.isEmpty()){
vector.add(data);
}
যদিও জড়িত পদ্ধতিগুলি সিঙ্ক্রোনাইজ করা হয়েছে, কারণ সেগুলি পৃথকভাবে লক করা এবং আনলক করা হচ্ছে, দুটি দুর্ভাগ্যক্রমে টাইমড থ্রেড দুটি উপাদান সহ একটি ভেক্টর তৈরি করতে পারে।
সুতরাং কার্যকরভাবে, আপনাকে আপনার অ্যাপ্লিকেশন কোডটিতেও সিঙ্ক্রোনাইজ করতে হবে।
কারণ পদ্ধতি-স্তরের সিঙ্ক্রোনাইজেশন ক) ব্যয়বহুল যখন আপনার প্রয়োজন হয় না এবং খ) আপনার যখন সিঙ্ক্রোনাইজেশন প্রয়োজন হয় তখন অপর্যাপ্ত, এখন আন-সিঙ্ক্রোনাইজড রিপ্লেসমেন্ট (ভেক্টরের ক্ষেত্রে অ্যারেলিস্ট) রয়েছে।
সাম্প্রতিককালে, একাধিক চৌকস ইউটিলিটিগুলি মাল্টি থ্রেডিং ইস্যুগুলিতে যত্ন নিয়ে সম্মতিযুক্ত প্যাকেজ প্রকাশ করা হয়েছে।
জাভাতে সিঙ্ক্রোনাইজ করা কীওয়ার্ডটি থ্রেড-সুরক্ষার সাথে করতে হবে, যখন একাধিক থ্রেড একই ভেরিয়েবলটি পড়ে বা লিখতে থাকে।
এটি সরাসরি (একই ভেরিয়েবল অ্যাক্সেসের মাধ্যমে) বা অপ্রত্যক্ষভাবে (একই শ্রেণীর অ্যাক্সেস করে এমন একটি শ্রেণীর ব্যবহার করে যা অন্য শ্রেণীর ব্যবহার করে) ঘটতে পারে।
সিঙ্ক্রোনাইজ করা কীওয়ার্ড কোডের একটি ব্লক সংজ্ঞায়িত করতে ব্যবহৃত হয় যেখানে একাধিক থ্রেড নিরাপদ উপায়ে একই চলক অ্যাক্সেস করতে পারে।
সিনট্যাক্স-অনুসারে synchronizedকীওয়ার্ডটি Objectপ্যারামিটার হিসাবে নেয় (যাকে একটি লক অবজেক্ট বলা হয় ), যা এর পরে একটি হয় { block of code }।
যখন প্রয়োগটি এই কীওয়ার্ডটির মুখোমুখি হয়, বর্তমান থ্রেডটি লক অবজেক্টটি "লক / অর্জন / নিজের" করতে চেষ্টা করে ( তালা নেবে) এবং লকটি অর্জিত হওয়ার পরে সম্পর্কিত ব্লকের কোডটি কার্যকর করে।
সিঙ্ক্রোনাইজড কোড ব্লকের অভ্যন্তরে ভেরিয়েবলগুলিতে যে কোনও লেখার জন্য একইভাবে একই লক অবজেক্টটি ব্যবহার করে একটি সিঙ্ক্রোনাইজড কোড ব্লকের অভ্যন্তরে কোড কার্যকর করে এমন প্রতিটি থ্রেডের কাছে দৃশ্যমান হওয়ার নিশ্চয়তা দেওয়া হয় ।
একবারে কেবল একটি থ্রেড লকটি ধরে রাখতে পারে, সেই সময় একই লক অবজেক্টটি অর্জন করার চেষ্টা করছে এমন অন্যান্য সমস্ত থ্রেড অপেক্ষা করবে (তাদের মৃত্যুদন্ড স্থগিত করুন)। এক্সিকিউশন সিঙ্ক্রোনাইজড কোড ব্লক থেকে বেরিয়ে গেলে লকটি প্রকাশ করা হবে।
যোগ করার পদ্ধতি synchronizedএকটি পদ্ধতি সংজ্ঞা শব্দ সমগ্র পদ্ধতি শরীর সমান সঙ্গে সুসংগত কোড ব্লক আবৃত হচ্ছে লক বস্তু হচ্ছে this (উদাহরণস্বরূপ পদ্ধতি জন্য) এবং ClassInQuestion.getClass() (ক্লাস পদ্ধতি জন্য) ।
- ইনস্ট্যান্স পদ্ধতিটি এমন একটি পদ্ধতি যার staticকীওয়ার্ড নেই।
- ক্লাস পদ্ধতিটি এমন একটি পদ্ধতি যা staticকীওয়ার্ড থাকে।
সিঙ্ক্রোনাইজেশন ব্যতীত, কোনও পাঠ্য ও লেখার ক্রম ঘটতে পারে তা গ্যারান্টিযুক্ত নয়, সম্ভবত ভেরিয়েবলটি আবর্জনা দিয়ে ফেলে।
(উদাহরণস্বরূপ একটি চলক একটি থ্রেড দ্বারা রচিত বিটগুলির অর্ধেক এবং অন্য থ্রেড দ্বারা রচিত বিটগুলির অর্ধেক সমাপ্ত হতে পারে, ভেরিয়েবলটি এমন অবস্থায় ছেড়ে যায় যে উভয় থ্রেডই লেখার চেষ্টা করেনি, তবে উভয়ের সম্মিলিত জগাখিচুড়ি।)
আর কোনও থ্রেড এটি পড়ার আগে কোনও থ্রেডে রাইটিং অপারেশন সম্পন্ন করা যথেষ্ট নয়, কারণ হার্ডওয়্যার ভেরিয়েবলের মান ক্যাশে করতে পারে, এবং পাঠ্য থ্রেডে যা লেখা হয়েছিল তার পরিবর্তে ক্যাশেড মানটি দেখতে পেত would এটা।
জাভা ক্ষেত্রে, থ্রেডিং ত্রুটি যাতে না ঘটে তা নিশ্চিত করতে আপনাকে জাভা মেমোরি মডেলটি অনুসরণ করতে হবে।
অন্য কথায়: সিঙ্ক্রোনাইজেশন, পারমাণবিক ক্রিয়াকলাপ বা ক্লাসগুলি ব্যবহার করুন যা সেগুলি আপনার জন্য ফণীর নীচে ব্যবহার করে।
সোর্স
http://docs.oracle.com/javase/specs/jls/se8/html/index.html
জাভা ভাষা স্পেসিফিকেশন, 2015-02-13
এটিকে একধরণের ঘুরিয়ে ফেলার মতো ভাবুন আপনি কোনও ফুটবলের মাঠে খুঁজে পেতে পারেন। সেখানে প্রবেশ করতে চায় এমন সমান্তরাল বাষ্প রয়েছে তবে টার্নসটেলে তারা 'সিঙ্ক্রোনাইজড' হয়। একসাথে কেবল একজন ব্যক্তি এটি পেতে পারেন। যারা এর মধ্যে যেতে চান তারা সমস্তই করবে, তবে তাদের পেরিয়ে যাওয়ার আগে তাদের অপেক্ষা করতে হতে পারে।
সিঙ্ক্রোনাইজ করা কীওয়ার্ড কী?
থ্রেডগুলি প্রাথমিকভাবে ক্ষেত্রগুলিতে অ্যাক্সেস ভাগ করে এবং অবজেক্ট রেফারেন্স ক্ষেত্রগুলি উল্লেখ করে communicate যোগাযোগের এই ফর্মটি অত্যন্ত দক্ষ, তবে দুটি ধরণের ত্রুটিকে সম্ভব করে তোলে: থ্রেড হস্তক্ষেপ এবং মেমরির ধারাবাহিকতা ত্রুটি । এই ত্রুটিগুলি রোধ করার জন্য প্রয়োজনীয় সরঞ্জামটি সিঙ্ক্রোনাইজেশন।
সিঙ্ক্রোনাইজড ব্লক বা পদ্ধতিগুলি থ্রেড হস্তক্ষেপকে বাধা দেয় এবং নিশ্চিত করুন যে ডেটাটি সামঞ্জস্যপূর্ণ। যে কোনও সময়ে, শুধুমাত্র একটি থ্রেড লক অর্জনের মাধ্যমে একটি সিঙ্ক্রোনাইজড ব্লক বা পদ্ধতি ( সমালোচনা বিভাগ ) অ্যাক্সেস করতে পারে । অন্যান্য থ্রেডগুলি সমালোচনামূলক বিভাগ অ্যাক্সেস করতে লক প্রকাশের অপেক্ষায় থাকবে ।
পদ্ধতিগুলি কখন সিঙ্ক্রোনাইজ হয়?
আপনি যখন synchronizedপদ্ধতি সংজ্ঞা বা ঘোষণায় যুক্ত হন তখন পদ্ধতিগুলি সিঙ্ক্রোনাইজ হয় । আপনি কোনও পদ্ধতির সাথে কোডের একটি নির্দিষ্ট ব্লককেও সিঙ্ক্রোনাইজ করতে পারেন।
ব্যাকরণগতভাবে এবং যৌক্তিকভাবে এর অর্থ কী?
এর অর্থ হ'ল শুধুমাত্র একটি থ্রেড লক অর্জনের মাধ্যমে সমালোচনা বিভাগে অ্যাক্সেস করতে পারে । যদি এই থ্রেডটি এই লকটি প্রকাশ না করে, অন্য সমস্ত থ্রেড (গুলি) লকটি অর্জনের জন্য অপেক্ষা করতে হবে। তাদের কাছে সমালোচনা বিভাগে প্রবেশের অ্যাক্সেস নেইলক অর্জনের সাথে তাদের ।
যাদু দিয়ে এটি করা যায় না। সমালোচনামূলক বিভাগ (গুলি) সনাক্ত করার জন্য এটি প্রোগ্রামারের দায়িত্বপ্রয়োগের করা এবং তদনুসারে এটি রক্ষা । আপনার অ্যাপ্লিকেশনটি রক্ষা করার জন্য জাভা একটি কাঠামো সরবরাহ করে তবে কোথায় এবং কীভাবে সমস্ত বিভাগ রক্ষা করা উচিত তা প্রোগ্রামারের দায়িত্ব।
জাভা ডকুমেন্টেশন পৃষ্ঠা থেকে আরও বিশদ
অন্তর্নিহিত লক্স এবং সিঙ্ক্রোনাইজেশন:
সিঙ্ক্রোনাইজেশন একটি অভ্যন্তরীণ সত্তা চারপাশে নির্মিত হয় যা অন্তর্নিহিত লক বা মনিটর লক হিসাবে পরিচিত। অন্তর্নিহিত লকগুলি সিঙ্ক্রোনাইজেশনের উভয় দিকগুলিতে ভূমিকা রাখে: কোনও বস্তুর রাজ্যে একচেটিয়া অ্যাক্সেস প্রয়োগ করে এবং দৃশ্যমানতার জন্য অপরিহার্য সম্পর্কগুলির আগে ঘটে।
প্রতিটি বস্তুর একটি স্বকীয় এর সাথে জড়িত লক হয়েছে । কনভেনশন অনুসারে, কোনও থ্রেড যা কোনও সামগ্রীর ক্ষেত্রগুলিতে একচেটিয়া এবং ধারাবাহিক অ্যাক্সেসের প্রয়োজন সেগুলিতে অ্যাক্সেস করার আগে অবজেক্টের অভ্যন্তরীণ লকটি অর্জন করতে হবে এবং তার সাথে শেষ হয়ে গেলে অভ্যন্তরীণ লকটি প্রকাশ করতে হবে।
কোনও থ্রেড লকটি অর্জন এবং লকটি প্রকাশের সময়ের মধ্যে অভ্যন্তরীণ লকটির মালিক বলে বলা হয়। যতক্ষণ কোনও থ্রেড অভ্যন্তরীণ লকের মালিক, অন্য কোনও থ্রেড একই লকটি অর্জন করতে পারে না। অন্য থ্রেডটি লকটি অর্জন করার চেষ্টা করলে এটি অবরুদ্ধ হবে।
যখন কোনও থ্রেড একটি অভ্যন্তরীণ লক প্রকাশ করে, সেই ক্রিয়া এবং একই লকের পরবর্তী কোনও অধিগ্রহণের মধ্যে একটি ঘটনার আগে সম্পর্ক স্থাপন করা হয়।
পদ্ধতিগুলি সিঙ্ক্রোনাইজড করার দুটি প্রভাব রয়েছে :
প্রথমত, একই বস্তুতে ইন্টারলিওয়েতে দুটি সিঙ্ক্রোনাইজড পদ্ধতির অনুরোধ করা সম্ভব নয়।
যখন একটি থ্রেড কোনও অবজেক্টের জন্য একটি সিঙ্ক্রোনাইজড পদ্ধতি কার্যকর করে, অন্য সমস্ত থ্রেড যা একই বস্তু ব্লকের (স্থগিতাদেশ স্থগিতের) জন্য সিনক্রোনাইজড পদ্ধতিগুলিকে অনুরোধ করে যতক্ষণ না বস্তুটির সাথে প্রথম থ্রেডটি সম্পন্ন হয়।
দ্বিতীয়ত, যখন একটি সিঙ্ক্রোনাইজড পদ্ধতিটি প্রস্থান করে, এটি স্বয়ংক্রিয়ভাবে একই বস্তুর জন্য একটি সিঙ্ক্রোনাইজড পদ্ধতির পরবর্তী কোনও অনুরোধের সাথে একটি ঘটনার আগে সম্পর্ক স্থাপন করে।
এটি গ্যারান্টি দেয় যে অবজেক্টের অবস্থানে পরিবর্তনগুলি সমস্ত থ্রেডে দৃশ্যমান।
সিঙ্ক্রোনাইজেশনের অন্যান্য বিকল্পগুলি এতে দেখুন:
Synchronized normal methodসমান
Synchronized statement(এটি ব্যবহার করুন)
class A {
public synchronized void methodA() {
// all function code
}
equivalent to
public void methodA() {
synchronized(this) {
// all function code
}
}
}
Synchronized static methodসমান Synchronized statement(ব্যবহার শ্রেণি)
class A {
public static synchronized void methodA() {
// all function code
}
equivalent to
public void methodA() {
synchronized(A.class) {
// all function code
}
}
}
সিঙ্ক্রোনাইজড স্টেটমেন্ট (ভেরিয়েবল ব্যবহার করে)
class A {
private Object lock1 = new Object();
public void methodA() {
synchronized(lock1 ) {
// all function code
}
}
}
জন্য synchronized, আমরা উভয় আছে Synchronized Methodsএবং Synchronized Statements। যাইহোক, Synchronized Methodsঅনুরূপ Synchronized Statementsতাই আমাদের কেবল বুঝতে হবে Synchronized Statements।
=> মূলত, আমাদের হবে
synchronized(object or class) { // object/class use to provides the intrinsic lock
// code
}
এখানে 2 মনে হয় এটি বুঝতে সহায়তা করে synchronized
intrinsic lockএটির সাথে সম্পর্কিত রয়েছে।synchronized statement, এটি স্বয়ংক্রিয়ভাবে intrinsic lockসেই synchronized statement'sবস্তুর জন্য অর্জন করে এবং যখন পদ্ধতিটি ফিরে আসে তখন তা প্রকাশ করে। যতক্ষণ কোনও থ্রেডের মালিক intrinsic lock, ততক্ষণ অন্য কোনও থ্রেড একই লক => থ্রেডটি নিরাপদ অর্জন করতে পারে না ।=> যখন একটি thread Aআহ্বান synchronized(this){// code 1}=> সমস্ত ব্লক কোড (শ্রেণীর অভ্যন্তরে) যেখানে থাকে synchronized(this)এবং সমস্ত synchronized normal method(শ্রেণির অভ্যন্তরে) লক থাকে কারণ একই লক হয়। এটি thread Aআনলক করার পরে কার্যকর হবে ("// কোড 1" সমাপ্ত)।
এই আচরণ অনুরূপ synchronized(a variable){// code 1}বা synchronized(class)।
একই লক => লক (কোন পদ্ধতির উপর নির্ভর করে না? বা কোন বিবৃতিতে?)
আমি পছন্দ করি synchronized statementsকারণ এটি আরও প্রসারিত। উদাহরণস্বরূপ, ভবিষ্যতে আপনার কেবল পদ্ধতির একটি অংশ সিঙ্ক্রোনাইজ করা দরকার। উদাহরণস্বরূপ, আপনার কাছে দুটি সিঙ্ক্রোনাইজড পদ্ধতি রয়েছে এবং এটি একে অপরের সাথে কোনও প্রাসঙ্গিক নয় , তবে কোনও থ্রেড যখন কোনও পদ্ধতি চালায় তখন এটি অন্য পদ্ধতিটি ব্লক করে দেবে (এটি ব্যবহারের মাধ্যমে প্রতিরোধ করতে পারে synchronized(a variable))।
তবে সিঙ্ক্রোনাইজড পদ্ধতিটি সহজ এবং কোডটি সহজ দেখাচ্ছে apply কিছু শ্রেণীর জন্য, কেবলমাত্র 1 টি সিঙ্ক্রোনাইজড পদ্ধতি বা ক্লাসের সমস্ত সিঙ্ক্রোনাইজড পদ্ধতি একে অপরের সাথে প্রাসঙ্গিক => আমরা synchronized methodকোডকে ছোট এবং সহজ করে বোঝার জন্য ব্যবহার করতে পারি
(এটি খুব বেশি প্রাসঙ্গিক নয় synchronized, এটি বস্তু এবং শ্রেণি বা কোনও নয়-স্থির এবং স্থির মধ্যে আলাদা)।
synchronizedবা সাধারণ পদ্ধতি বা synchronized(this)বা synchronized(non-static variable)এটি প্রতিটি বস্তুর উদাহরণের ভিত্তিতে সিঙ্ক্রোনাইজ হবে। synchronizedবা স্থির পদ্ধতি বা synchronized(class)বা synchronized(static variable)এটি ক্লাসের ভিত্তিতে বেস সিঙ্ক্রোনাইজ হবেhttps://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
আশা করি এটি সাহায্য করবে
জাভা টিউটোরিয়ালগুলি থেকে এখানে একটি ব্যাখ্যা দেওয়া হয়েছে ।
নিম্নলিখিত কোড বিবেচনা করুন:
public class SynchronizedCounter { private int c = 0; public synchronized void increment() { c++; } public synchronized void decrement() { c--; } public synchronized int value() { return c; } }যদি এটির
countউদাহরণস্বরূপ হয়SynchronizedCounter, তবে এই পদ্ধতিগুলি সিঙ্ক্রোনাইজড করার দুটি প্রভাব রয়েছে:
- প্রথমত, একই বস্তুতে ইন্টারলিওয়েতে দুটি সিঙ্ক্রোনাইজড পদ্ধতির অনুরোধ করা সম্ভব নয়। যখন একটি থ্রেড কোনও অবজেক্টের জন্য একটি সিঙ্ক্রোনাইজড পদ্ধতি কার্যকর করে, অন্য সমস্ত থ্রেড যা একই বস্তু ব্লকের (স্থগিতাদেশ স্থগিতের) জন্য সিনক্রোনাইজড পদ্ধতিগুলিকে অনুরোধ করে যতক্ষণ না বস্তুটির সাথে প্রথম থ্রেডটি সম্পন্ন হয়।
- দ্বিতীয়ত, যখন একটি সিঙ্ক্রোনাইজড পদ্ধতিটি প্রস্থান করে, এটি স্বয়ংক্রিয়ভাবে একই বস্তুর জন্য একটি সিঙ্ক্রোনাইজড পদ্ধতির পরবর্তী কোনও অনুরোধের সাথে একটি ঘটনার আগে সম্পর্ক স্থাপন করে। এটি গ্যারান্টি দেয় যে অবজেক্টের অবস্থানে পরিবর্তনগুলি সমস্ত থ্রেডে দৃশ্যমান।
আমার বোঝার সাথে সিঙ্ক্রোনাইজ করা মূলত এর অর্থ হ'ল কম্পাইলারটি আপনার পদ্ধতির চারপাশে একটি মনিটর.এনটার এবং মনিটর.এক্সিট লিখুন। এটি কীভাবে ব্যবহৃত হবে তার উপর নির্ভর করে এটি থ্রেড নিরাপদ হতে পারে (আমার অর্থ হ'ল আপনি কীভাবে সিঙ্ক্রোনাইজড পদ্ধতিতে কোনও বিষয় লিখতে পারেন যা আপনার ক্লাস কী করবে তার উপর নির্ভর করে থ্রেডসেফ নয়)।
অন্যান্য উত্তরগুলি কী অনুপস্থিত তা হ'ল একটি গুরুত্বপূর্ণ দিক: মেমরির বাধা । থ্রেড সিঙ্ক্রোনাইজেশন মূলত দুটি করে অংশ : সিরিয়ালাইজেশন এবং দৃশ্যমানতা। আমি সবাইকে "জেভিএম মেমরি বাধা" এর জন্য গুগল করার পরামর্শ দিচ্ছি, কারণ এটি একটি অ-তুচ্ছ এবং অত্যন্ত গুরুত্বপূর্ণ বিষয় (যদি আপনি একাধিক থ্রেড দ্বারা অ্যাক্সেস করা ভাগ করা ডেটা পরিবর্তন করেন)। এটি সম্পন্ন করার পরে, আমি java.util.concurrent প্যাকেজের ক্লাসগুলি দেখার পরামর্শ দিচ্ছি যা স্পষ্টত সিঙ্ক্রোনাইজেশন ব্যবহার এড়াতে সহায়তা করে, যা ফলস্বরূপ প্রোগ্রামগুলি সহজ এবং দক্ষ রাখতে সাহায্য করে, এমনকি ডেডলকগুলি রোধ করে।
এরকম একটি উদাহরণ কনক্র্যান্টলিঙ্কডেক । কমান্ডের প্যাটার্নের সাথে একসাথে কমান্ডগুলি সমবর্তী সারিতে ভরাট করে অত্যন্ত দক্ষ কর্মী থ্রেড তৈরি করতে দেয় - কোনও সুস্পষ্ট সিঙ্ক্রোনাইজেশন প্রয়োজন হয় না, কোনও অচলিত সম্ভাবনা নেই, কোনও সুস্পষ্ট ঘুম প্রয়োজন () প্রয়োজন নেই, কেবল কল () কল করে কাতারে পোল করুন।
সংক্ষেপে: "মেমরি সিঙ্ক্রোনাইজেশন" স্পষ্টভাবে ঘটে যখন আপনি একটি থ্রেড শুরু করবেন, একটি থ্রেড শেষ হবে, আপনি একটি উদ্বায়ী ভেরিয়েবলটি পড়বেন, আপনি একটি মনিটরকে আনলক করুন (একটি সিঙ্ক্রোনাইজড ব্লক / ফাংশন ছেড়ে যান) ইত্যাদি "এই" সিঙ্ক্রোনাইজেশন "প্রভাবিত করে (এক অর্থে" ফ্লাশ করে " ") সমস্ত নির্দিষ্ট লেখার আগে সেই বিশেষ ক্রিয়াটি সম্পন্ন হয়েছিল। পূর্বোক্ত কনক্র্যান্টলিঙ্কডেকের ক্ষেত্রে ডকুমেন্টেশনটি "বলেছেন":
মেমোরি ধারাবাহিকতা প্রভাবগুলি: অন্যান্য সমবর্তী সংগ্রহগুলির মতো, কোনও থ্রেডে সামঞ্জস্যলিঙ্কডেক থেকে সেই উপাদানটির অ্যাক্সেস বা অপসারণের পরবর্তী ক্রিয়াকলাপের আগে কোনও বস্তুটিকে কনকন্টুরিলিংডডিকের মধ্যে স্থাপন করার আগে একটি থ্রেডে ক্রিয়াগুলি।
এই অন্তর্নিহিত আচরণটি কিছুটা ক্ষতিকারক দিক কারণ অনেক অভিজ্ঞতা ছাড়াই বেশিরভাগ জাভা প্রোগ্রামাররা এর কারণে প্রদত্ত হিসাবে অনেক কিছু নেবে। এবং তারপরে হঠাৎ এই থ্রেডটিতে হোঁচট খাওয়ার পরে জাভা এমন কিছু করছে না যেখানে উত্পাদনে এটি করা উচিত "অনুমিত" যেখানে আলাদা কাজের বোঝা রয়েছে - এবং একমত হওয়া বিষয়গুলি পরীক্ষা করা বেশ শক্ত।
সিঙ্ক্রোনাইজ করা সহজভাবে এর অর্থ হ'ল একক বস্তুর সাথে সম্পর্কিত হলে একাধিক থ্রেডগুলি নির্দিষ্ট বস্তুতে সিঙ্ক্রোনাইজড ব্লক ব্যবহার করা হলে মলিন পড়া এবং লিখতে বাধা দিতে পারে। আপনাকে আরও স্পষ্টতা দিতে, একটি উদাহরণ নেওয়া যাক:
class MyRunnable implements Runnable {
int var = 10;
@Override
public void run() {
call();
}
public void call() {
synchronized (this) {
for (int i = 0; i < 4; i++) {
var++;
System.out.println("Current Thread " + Thread.currentThread().getName() + " var value "+var);
}
}
}
}
public class MutlipleThreadsRunnable {
public static void main(String[] args) {
MyRunnable runnable1 = new MyRunnable();
MyRunnable runnable2 = new MyRunnable();
Thread t1 = new Thread(runnable1);
t1.setName("Thread -1");
Thread t2 = new Thread(runnable2);
t2.setName("Thread -2");
Thread t3 = new Thread(runnable1);
t3.setName("Thread -3");
t1.start();
t2.start();
t3.start();
}
}
আমরা দুটি মাইআরনেবল ক্লাস অবজেক্ট তৈরি করেছি, রানডেবল 1 থ্রেড 1 এবং থ্রেড 3 এবং রান্নেবল 2 ভাগ করে কেবল থ্রেড 2 দিয়ে ভাগ করা হচ্ছে। এখন যখন টি 1 এবং টি 3 সিঙ্ক্রোনাইজ করা ব্যবহার না করে শুরু হয়, পিএফবি আউটপুট যা উভয় থ্রেড 1 এবং 3 একই সাথে ভেরু মানকে প্রভাবিত করে যেখানে থ্রেড 2, ভার এর নিজস্ব স্মৃতি রয়েছে suggest
Without Synchronized keyword
Current Thread Thread -1 var value 11
Current Thread Thread -2 var value 11
Current Thread Thread -2 var value 12
Current Thread Thread -2 var value 13
Current Thread Thread -2 var value 14
Current Thread Thread -1 var value 12
Current Thread Thread -3 var value 13
Current Thread Thread -3 var value 15
Current Thread Thread -1 var value 14
Current Thread Thread -1 var value 17
Current Thread Thread -3 var value 16
Current Thread Thread -3 var value 18
সিঙ্ক্রোনজিড ব্যবহার করে থ্রেড 3 সমস্ত দৃশ্যে সম্পূর্ণ থ্রেড 1 এর অপেক্ষায়। দুটি লক অধিগ্রহণ করা হয়েছে, একটি থ্রেড 1 এবং থ্রেড 3 দ্বারা ভাগ করা চালানোযোগ্য 1 এ এবং অন্যটি রান্নেবল 2 এ কেবল থ্রেড 2 দ্বারা ভাগ করা হয়েছে।
Current Thread Thread -1 var value 11
Current Thread Thread -2 var value 11
Current Thread Thread -1 var value 12
Current Thread Thread -2 var value 12
Current Thread Thread -1 var value 13
Current Thread Thread -2 var value 13
Current Thread Thread -1 var value 14
Current Thread Thread -2 var value 14
Current Thread Thread -3 var value 15
Current Thread Thread -3 var value 16
Current Thread Thread -3 var value 17
Current Thread Thread -3 var value 18
সিঙ্ক্রোনাইজড সরল মানে কোনও দুটি থ্রেড একই সাথে ব্লক / পদ্ধতিতে অ্যাক্সেস করতে পারে না। আমরা যখন বলি যে কোনও শ্রেণীর যে কোনও ব্লক / পদ্ধতি সিঙ্ক্রোনাইজ করা হয়েছে এর অর্থ একটি সময়ে কেবল একটি থ্রেড এগুলি অ্যাক্সেস করতে পারে। অভ্যন্তরীণভাবে যে থ্রেডটি এটি অ্যাক্সেস করার চেষ্টা করে সেটি প্রথমে সেই বস্তুর উপর একটি লক নেয় এবং যতক্ষণ না এই লকটি পাওয়া যায় না ততক্ষণ অন্য কোনও থ্রেড ক্লাসের সেই উদাহরণটির কোনও সিঙ্ক্রোনাইজড পদ্ধতি / ব্লকগুলিতে অ্যাক্সেস করতে পারে না।
নোট করুন অন্য থ্রেড একই পদার্থের এমন কোনও পদ্ধতিতে অ্যাক্সেস করতে পারে যা সংশ্লেষিত হওয়ার জন্য সংজ্ঞাযুক্ত নয়। একটি থ্রেড কল করে লকটি মুক্তি দিতে পারে
Object.wait()
synchronizedজাভা ব্লক মাল্টিথ্রেডিংয়ে একটি মনিটর। synchronizedএকই অবজেক্ট / ক্লাসের সাথে ব্লক কেবলমাত্র একক থ্রেড দ্বারা চালানো যেতে পারে, অন্যরা সবাই অপেক্ষা করছে। এটা দিয়ে সাহায্য করতে পারেন race conditionঅবস্থা যখন একাধিক থ্রেড (প্রথম ধাপ ব্যবহার করছে একই পরিবর্তনশীল আপডেট করার চেষ্টা volatileসম্পর্কে )
Java 5synchronizedসমর্থন দ্বারা প্রসারিত happens-before[সম্পর্কে]
একই মনিটরের পরবর্তী লক (সিঙ্ক্রোনাইজড ব্লক বা পদ্ধতি প্রবেশ) এর আগে একটি মনিটরের একটি আনলক (সিঙ্ক্রোনাইজড ব্লক বা পদ্ধতি প্রস্থান) ঘটে happens
পরবর্তী পদক্ষেপ হয় java.util.concurrent