কেউ কি আমাকে উদাহরণের সাথে সিঙ্ক্রোনাইজড ব্লকের ওপরে সিঙ্ক্রোনাইজড পদ্ধতির সুবিধা বলতে পারবেন?
কেউ কি আমাকে উদাহরণের সাথে সিঙ্ক্রোনাইজড ব্লকের ওপরে সিঙ্ক্রোনাইজড পদ্ধতির সুবিধা বলতে পারবেন?
উত্তর:
একটি উদাহরণ সহ সিঙ্ক্রোনাইজড ব্লকের মাধ্যমে কেউ আমাকে সিঙ্ক্রোনাইজড পদ্ধতির সুবিধা বলতে পারবেন? ধন্যবাদ।
ব্লকের উপরে সিঙ্ক্রোনাইজড পদ্ধতি ব্যবহারের সুস্পষ্ট সুবিধা নেই।
সম্ভবত একমাত্র (তবে আমি এটিকে কোনও সুবিধা বলব না) আপনাকে অবজেক্ট রেফারেন্স অন্তর্ভুক্ত করার দরকার নেই this
।
পদ্ধতি:
public synchronized void method() { // blocks "this" from here....
...
...
...
} // to here
ব্লক:
public void method() {
synchronized( this ) { // blocks "this" from here ....
....
....
....
} // to here...
}
দেখা? কোনও লাভ নেই
ব্লক কি বেশিরভাগই নমনীয়তা যদিও পদ্ধতি উপর সুবিধা আছে, কারণ আপনি লক যেমন অন্য বস্তুর ব্যবহার করতে পারেন পদ্ধতি সিঙ্ক সমগ্র বস্তু লক হবে যেহেতু।
তুলনা করা:
// locks the whole object
...
private synchronized void someInputRelatedWork() {
...
}
private synchronized void someOutputRelatedWork() {
...
}
বনাম
// Using specific locks
Object inputLock = new Object();
Object outputLock = new Object();
private void someInputRelatedWork() {
synchronized(inputLock) {
...
}
}
private void someOutputRelatedWork() {
synchronized(outputLock) {
...
}
}
এছাড়াও পদ্ধতিটি বৃদ্ধি পেলে আপনি এখনও সিঙ্ক্রোনাইজ করা বিভাগটি আলাদা রাখতে পারেন:
private void method() {
... code here
... code here
... code here
synchronized( lock ) {
... very few lines of code here
}
... code here
... code here
... code here
... code here
}
synchronized
ব্লক দুটি নির্দেশাবলীর সাহায্যে বাস্তবায়িত হয়, monitorenter
এবং monitorexit
, আরও একটি ব্যতিক্রম হ্যান্ডলার যা নিশ্চিত করে যে monitorexit
এটি ব্যতিক্রমী ক্ষেত্রেও বলা হয়। কোনও synchronized
পদ্ধতি ব্যবহার করার সময় এগুলি সবই সংরক্ষিত ।
একমাত্র আসল পার্থক্যটি হ'ল একটি সিঙ্ক্রোনাইজড ব্লকটি বেছে নিতে পারে যে এটি কোন বস্তুর সাথে সিঙ্ক্রোনাইজ হয়। একটি সিঙ্ক্রোনাইজড পদ্ধতি কেবলমাত্র 'this'
(বা একটি সিঙ্ক্রোনাইজ করা শ্রেণির পদ্ধতির জন্য সংশ্লিষ্ট শ্রেণীর উদাহরণ) ব্যবহার করতে পারে। উদাহরণস্বরূপ, এগুলি শব্দার্থগতভাবে সমতুল্য:
synchronized void foo() {
...
}
void foo() {
synchronized (this) {
...
}
}
পরবর্তীটি আরও নমনীয় যেহেতু এটি যে কোনও বস্তুর সাথে সম্পর্কিত লক , প্রায়শই সদস্যের পরিবর্তনশীলের জন্য প্রতিযোগিতা করতে পারে । এটি আরও দানাদার কারণ আপনার ব্লকের আগে এবং পরে সমবর্তী কোড কার্যকর করা হতে পারে তবে এখনও পদ্ধতির মধ্যে। অবশ্যই আপনি পৃথক নন-সিঙ্ক্রোনাইজড পদ্ধতিতে সমবর্তী কোডটি রিফ্যাক্ট করে ঠিক তত সহজেই একটি সিঙ্ক্রোনাইজড পদ্ধতি ব্যবহার করতে পারেন। কোডটি আরও বোধগম্য করে তোলে যা ব্যবহার করুন।
পেশাদাররা:
কনস:
পেশাদাররা:
কনস:
ব্যক্তিগতভাবে আমি ক্লাসগুলির সাথে সিঙ্ক্রোনাইজড মেথডগুলি কেবলমাত্র সিঙ্ক্রোনাইজেশনের প্রয়োজনীয় জিনিসটির দিকে দৃষ্টি নিবদ্ধ করে পছন্দ করি using এই ধরণের শ্রেণি যতটা সম্ভব ছোট হওয়া উচিত এবং তাই সিঙ্ক্রোনাইজেশন পর্যালোচনা করা সহজ হওয়া উচিত। অন্যদের সিঙ্ক্রোনাইজেশন সম্পর্কে যত্ন নেওয়া উচিত নয়।
মূল পার্থক্য হল, আপনি একটি সিঙ্ক্রোনাইজ ব্লক ব্যবহার আপনি ছাড়া অন্য একটি বস্তুর উপর লক পারে এই যা অনেক নমনীয় হতে পারবেন।
ধরে নিন আপনার কাছে একটি বার্তার সারি এবং একাধিক বার্তা প্রযোজক এবং গ্রাহক রয়েছে। আমরা চাই না যে প্রযোজকরা একে অপরের সাথে হস্তক্ষেপ করুক, তবে গ্রাহকদের প্রযোজকদের অপেক্ষা না করে বার্তাগুলি পুনরুদ্ধার করতে সক্ষম হওয়া উচিত। সুতরাং আমরা কেবল একটি বস্তু তৈরি
Object writeLock = new Object();
এবং এখন থেকে প্রতিবার কোনও প্রযোজক একটি নতুন বার্তা যুক্ত করতে চান আমরা কেবল এটি লক করে রেখেছি:
synchronized(writeLock){
// do something
}
সুতরাং গ্রাহকরা এখনও পড়তে পারেন এবং উত্পাদকরা লক হয়ে যাবে।
সিঙ্ক্রোনাইজড পদ্ধতি
সিঙ্ক্রোনাইজড পদ্ধতিতে দুটি প্রভাব রয়েছে।
প্রথমত, যখন একটি থ্রেড কোনও বস্তুর জন্য একটি সিঙ্ক্রোনাইজড পদ্ধতি চালায়, অন্য সমস্ত থ্রেড যা একই বস্তু ব্লকের (স্থগিতাদেশ স্থগিতকরণ) জন্য সিনক্রোনাইজড পদ্ধতিগুলিকে অনুরোধ করে যতক্ষণ না বস্তুর সাথে প্রথম থ্রেডটি সম্পন্ন হয়।
দ্বিতীয়ত, যখন একটি সিঙ্ক্রোনাইজড পদ্ধতিটি প্রস্থান করে, এটি স্বয়ংক্রিয়ভাবে একই বস্তুর জন্য একটি সিঙ্ক্রোনাইজড পদ্ধতির পরবর্তী কোনও অনুরোধের সাথে একটি ঘটনার আগে সম্পর্ক স্থাপন করে। এটি গ্যারান্টি দেয় যে অবজেক্টের অবস্থানে পরিবর্তনগুলি সমস্ত থ্রেডে দৃশ্যমান।
নোট করুন যে কনস্ট্রাক্টরগুলি সিঙ্ক্রোনাইজ করা যায় না - কনস্ট্রাক্টরের সাথে সিঙ্ক্রোনাইজ করা কীওয়ার্ড ব্যবহার করা একটি সিনট্যাক্স ত্রুটি। কনস্ট্রাক্টরগুলি সিঙ্ক্রোনাইজ করার কোনও অর্থ হয় না, কারণ কেবল থ্রেড যা কোনও অবজেক্ট তৈরি করে তার নির্মাণের সময় এটিতে অ্যাক্সেস থাকা উচিত।
সিঙ্ক্রোনাইজড স্টেটমেন্ট
সিঙ্ক্রোনাইজড পদ্ধতির থেকে পৃথক, সিঙ্ক্রোনাইজ করা স্টেটমেন্টগুলিতে অবশ্যই অবজেক্টটি নির্দিষ্ট করতে হবে যা অন্তর্গত লক সরবরাহ করে: বেশিরভাগ ক্ষেত্রে আমি এটি একটি তালিকা বা মানচিত্রের অ্যাক্সেসকে সিঙ্ক্রোনাইজ করতে ব্যবহার করি তবে আমি অবজেক্টের সমস্ত পদ্ধতির অ্যাক্সেসকে ব্লক করতে চাই না।
প্রশ্ন: অন্তর্নিহিত লক এবং সিঙ্ক্রোনাইজেশন সিঙ্ক্রোনাইজেশন একটি অভ্যন্তরীণ সত্তার চারপাশে অন্তর্নির্মিত হয় যা অভ্যন্তরীণ লক বা মনিটর লক হিসাবে পরিচিত। (এপিআই স্পেসিফিকেশন প্রায়শই এই সত্তাকে কেবল "মনিটর" হিসাবে উল্লেখ করে) অন্তর্নিহিত লকগুলি সিঙ্ক্রোনাইজেশনের উভয় দিকগুলিতে ভূমিকা রাখে: কোনও বস্তুর রাজ্যে একচেটিয়া অ্যাক্সেস প্রয়োগ করা এবং দৃশ্যমানতার জন্য প্রয়োজনীয় অপরিহার্য সম্পর্কগুলির আগেই সম্পর্ক স্থাপন করা।
প্রতিটি বস্তুর সাথে এর সাথে যুক্ত একটি অন্তর্গত লক রয়েছে। কনভেনশন অনুসারে, কোনও থ্রেডের জন্য যা কোনও বস্তুর ক্ষেত্রগুলিতে একচেটিয়া এবং ধারাবাহিক অ্যাক্সেসের প্রয়োজন সেগুলিতে অ্যাক্সেস করার আগে অবজেক্টের অভ্যন্তরীণ লকটি অর্জন করতে হবে এবং তার সাথে সম্পন্ন হওয়ার পরে তার অভ্যন্তরীণ লকটি প্রকাশ করতে হবে। কোনও থ্রেড লকটি অর্জন এবং লকটি প্রকাশের সময়ের মধ্যে অভ্যন্তরীণ লকটির মালিক বলে বলা হয়। যতক্ষণ কোনও থ্রেড অভ্যন্তরীণ লকের মালিক, অন্য কোনও থ্রেড একই লকটি অর্জন করতে পারে না। অন্য থ্রেডটি লকটি অর্জন করার চেষ্টা করলে এটি অবরুদ্ধ হবে।
package test;
public class SynchTest implements Runnable {
private int c = 0;
public static void main(String[] args) {
new SynchTest().test();
}
public void test() {
// Create the object with the run() method
Runnable runnable = new SynchTest();
Runnable runnable2 = new SynchTest();
// Create the thread supplying it with the runnable object
Thread thread = new Thread(runnable,"thread-1");
Thread thread2 = new Thread(runnable,"thread-2");
// Here the key point is passing same object, if you pass runnable2 for thread2,
// then its not applicable for synchronization test and that wont give expected
// output Synchronization method means "it is not possible for two invocations
// of synchronized methods on the same object to interleave"
// Start the thread
thread.start();
thread2.start();
}
public synchronized void increment() {
System.out.println("Begin thread " + Thread.currentThread().getName());
System.out.println(this.hashCode() + "Value of C = " + c);
// If we uncomment this for synchronized block, then the result would be different
// synchronized(this) {
for (int i = 0; i < 9999999; i++) {
c += i;
}
// }
System.out.println("End thread " + Thread.currentThread().getName());
}
// public synchronized void decrement() {
// System.out.println("Decrement " + Thread.currentThread().getName());
// }
public int value() {
return c;
}
@Override
public void run() {
this.increment();
}
}
সিঙ্ক্রোনাইজড পদ্ধতি, ব্লক এবং সিঙ্ক্রোনাইজেশন ছাড়াই ক্রসগুলি বিভিন্ন আউটপুটগুলি পরীক্ষা করে।
জাভা সংকলক যখন আপনার উত্স কোডটি বাইট কোডে রূপান্তরিত করে, তখন এটি সিঙ্ক্রোনাইজড পদ্ধতিগুলি এবং সিঙ্ক্রোনাইজড ব্লকগুলিকে খুব আলাদাভাবে পরিচালনা করে hand
যখন জেভিএম একটি সিঙ্ক্রোনাইজড পদ্ধতি চালায়, এক্সিকিউটিভ থ্রেড শনাক্ত করে যে পদ্ধতিটির মেথড_ইনফো কাঠামোটিতে এসিসিএসওয়াইএনসিআরসিএনআরইড পতাকা রয়েছে, তারপরে এটি স্বয়ংক্রিয়ভাবে বস্তুর লকটি অর্জন করে, পদ্ধতিটি কল করে এবং লকটি প্রকাশ করে। যদি কোনও ব্যতিক্রম ঘটে তবে থ্রেডটি স্বয়ংক্রিয়ভাবে লকটি প্রকাশ করে।
অন্যদিকে কোনও মেথড ব্লককে সিঙ্ক্রোনাইজ করা, কোনও অবজেক্টের লক এবং ব্যতিক্রম হ্যান্ডলিং অর্জনের জন্য জেভিএম এর অন্তর্নির্মিত সমর্থনকে বাইপাস করে এবং কার্যকারিতা স্পষ্টভাবে বাইট কোডে লেখা উচিত। আপনি যদি একটি সিঙ্ক্রোনাইজড ব্লক সহ কোনও পদ্ধতির জন্য বাইট কোডটি পড়েন তবে আপনি এই কার্যকারিতাটি পরিচালনা করতে এক ডজনেরও বেশি অতিরিক্ত ক্রিয়াকলাপ দেখতে পাবেন।
এটি একটি সিঙ্ক্রোনাইজড পদ্ধতি এবং একটি সিঙ্ক্রোনাইজড ব্লক উভয়ই উত্পাদন করার জন্য কলগুলি দেখায়:
public class SynchronizationExample {
private int i;
public synchronized int synchronizedMethodGet() {
return i;
}
public int synchronizedBlockGet() {
synchronized( this ) {
return i;
}
}
}
synchronizedMethodGet()
পদ্ধতি নিম্নলিখিত বাইট কোড জেনারেট করে:
0: aload_0
1: getfield
2: nop
3: iconst_m1
4: ireturn
এবং synchronizedBlockGet()
পদ্ধতিটি থেকে এখানে বাইট কোডটি রয়েছে :
0: aload_0
1: dup
2: astore_1
3: monitorenter
4: aload_0
5: getfield
6: nop
7: iconst_m1
8: aload_1
9: monitorexit
10: ireturn
11: astore_2
12: aload_1
13: monitorexit
14: aload_2
15: athrow
সিঙ্ক্রোনাইজড মেথড এবং ব্লকের মধ্যে একটি উল্লেখযোগ্য পার্থক্য হ'ল সিঙ্ক্রোনাইজড ব্লক সাধারণত লকের স্কোপ হ্রাস করে। যেহেতু লকের স্কোপ পারফরম্যান্সের সাথে বিপরীতভাবে সমানুপাতিক, কেবল কোডের সমালোচনামূলক বিভাগটি লক করা সর্বদা ভাল। সিঙ্ক্রোনাইজড ব্লকটি ব্যবহারের সর্বোত্তম উদাহরণ হ'ল সিঙ্গলটন প্যাটার্নে ডাবল চেক লক করা যেখানে পুরো getInstance()
পদ্ধতিটি লক করার পরিবর্তে আমরা কেবল কোডের সমালোচনামূলক বিভাগটি লক করে থাকি যা সিঙ্গলটন উদাহরণ তৈরি করতে ব্যবহৃত হয়। এটি পারফরম্যান্সকে মারাত্মকভাবে উন্নতি করে কারণ লকিংয়ের জন্য কেবল এক বা দুই বার প্রয়োজন হয়।
সিঙ্ক্রোনাইজড পদ্ধতি ব্যবহার করার সময়, আপনি যদি স্ট্যাটিক সিঙ্ক্রোনাইজড এবং নন-স্ট্যাটিক সিঙ্ক্রোনাইজড পদ্ধতি দুটি মিশ্রিত করেন তবে আপনাকে অতিরিক্ত যত্ন নিতে হবে।
monitorenter
এবং যুক্ত করবে monitorexit
।
প্রায়শই আমি এটি কোনও তালিকা বা মানচিত্রের অ্যাক্সেসকে সিঙ্ক্রোনাইজ করতে ব্যবহার করি তবে আমি অবজেক্টের সমস্ত পদ্ধতির অ্যাক্সেসকে ব্লক করতে চাই না।
নিম্নলিখিত কোডে একটি থ্রেড তালিকা সংশোধন করে এমন কোনও থ্রেডের অপেক্ষায় অবরুদ্ধ হবে না যা মানচিত্রটি সংশোধন করছে। পদ্ধতিগুলি যদি বস্তুটির সাথে সিঙ্ক্রোনাইজ করা হয় তবে প্রতিটি পদ্ধতিটির জন্য অপেক্ষা করতে হবে যদিও তারা যে পরিবর্তনগুলি করছে তা বিরোধী নয়।
private List<Foo> myList = new ArrayList<Foo>();
private Map<String,Bar) myMap = new HashMap<String,Bar>();
public void put( String s, Bar b ) {
synchronized( myMap ) {
myMap.put( s,b );
// then some thing that may take a while like a database access or RPC or notifying listeners
}
}
public void hasKey( String s, ) {
synchronized( myMap ) {
myMap.hasKey( s );
}
}
public void add( Foo f ) {
synchronized( myList ) {
myList.add( f );
// then some thing that may take a while like a database access or RPC or notifying listeners
}
}
public Thing getMedianFoo() {
Foo med = null;
synchronized( myList ) {
Collections.sort(myList);
med = myList.get(myList.size()/2);
}
return med;
}
প্রতিচ্ছবি এপিআই ব্যবহার করে সিঙ্ক্রোনাইজড পদ্ধতিগুলি পরীক্ষা করা যায়। এটি কিছু চুক্তি পরীক্ষার জন্য কার্যকর হতে পারে যেমন মডেলের সমস্ত পদ্ধতি সিঙ্ক্রোনাইজ করা হয় ।
নিম্নলিখিত স্নিপেট হ্যাশটেবলের সমস্ত সিঙ্ক্রোনাইজড পদ্ধতি মুদ্রণ করে:
for (Method m : Hashtable.class.getMethods()) {
if (Modifier.isSynchronized(m.getModifiers())) {
System.out.println(m);
}
}
সিঙ্ক্রোনাইজড ব্লকটি ব্যবহারের বিষয়ে গুরুত্বপূর্ণ নোট: আপনি লক অবজেক্ট হিসাবে যা ব্যবহার করেন তা সাবধান!
উপরের ইউজার 2277816 এর কোড স্নিপেট এই পয়েন্টটি তুলে ধরেছে যে স্ট্রিং আক্ষরিকের জন্য একটি রেফারেন্স লকিং অবজেক্ট হিসাবে ব্যবহৃত হয়। বুঝতে পারেন যে স্ট্রিং লিটারালগুলি স্বয়ংক্রিয়ভাবে জাভাতে অভ্যন্তরীণ হয় এবং আপনার সমস্যাটি দেখা শুরু করা উচিত: কোডের প্রতিটি অংশ যা আক্ষরিক "লক" এ সিঙ্ক্রোনাইজ করে, একই লকটি ভাগ করে! এটি সহজেই কোডের সম্পূর্ণ সম্পর্কহীন টুকরা সহ ডেডলকগুলিতে নিয়ে যেতে পারে।
এটি কেবল স্ট্রিং অবজেক্টই নয় যা আপনার সাবধান হওয়া উচিত। বাক্সযুক্ত আদিমগুলিও একটি বিপদ, যেহেতু অটোবক্সিং এবং মানফল পদ্ধতিগুলি একই মানকে পুনরায় ব্যবহার করতে পারে, মানটির উপর নির্ভর করে।
আরও তথ্যের জন্য দেখুন: https://www.securecoding.cert.org/confluence/display/java/LCK01-J.+Do+not+Synchronize+on+objects+that+ma++++used
প্রায়শই কোনও পদ্ধতি স্তরে লক ব্যবহার করা খুব অভদ্র। কেন এমন কোনও কোডের লক আপ করুন যা কোনও সম্পূর্ণ পদ্ধতি লক করে কোনও ভাগ করা সংস্থানগুলিতে অ্যাক্সেস করে না। যেহেতু প্রতিটি বস্তুর একটি লক রয়েছে তাই আপনি ব্লক স্তর সমলয়কে কার্যকর করতে ডামি অবজেক্ট তৈরি করতে পারেন। ব্লক স্তরটি আরও কার্যকর কারণ এটি পুরো পদ্ধতিটিকে লক করে না।
এখানে কিছু উদাহরণ
পদ্ধতি স্তর
class MethodLevel {
//shared among threads
SharedResource x, y ;
public void synchronized method1() {
//multiple threads can't access
}
public void synchronized method2() {
//multiple threads can't access
}
public void method3() {
//not synchronized
//multiple threads can access
}
}
ব্লক স্তর
class BlockLevel {
//shared among threads
SharedResource x, y ;
//dummy objects for locking
Object xLock = new Object();
Object yLock = new Object();
public void method1() {
synchronized(xLock){
//access x here. thread safe
}
//do something here but don't use SharedResource x, y
// because will not be thread-safe
synchronized(xLock) {
synchronized(yLock) {
//access x,y here. thread safe
}
}
//do something here but don't use SharedResource x, y
//because will not be thread-safe
}//end of method1
}
[সম্পাদনা]
জন্য Collection
মত Vector
এবং Hashtable
তারা সিঙ্ক্রোনাইজ যখন হয় ArrayList
বা HashMap
না হয় এবং আপনি শব্দ সিঙ্ক্রোনাইজ বা ডাকা সংগ্রহগুলি সিঙ্ক্রোনাইজ পদ্ধতি সেট প্রয়োজন:
Map myMap = Collections.synchronizedMap (myMap); // single lock for the entire map
List myList = Collections.synchronizedList (myList); // single lock for the entire list
পার্থক্য: সিঙ্ক্রোনাইজড ব্লকগুলি সিঙ্ক্রোনাইজড পদ্ধতির বিপরীতে দানাদার লকিংয়ের অনুমতি দেয়
মূলত synchronized
মেমোরি অসঙ্গতি ত্রুটি এড়িয়ে থ্রেড নিরাপদ কোড লেখার জন্য ব্লক বা পদ্ধতিগুলি ব্যবহার করা হয়েছে।
এই প্রশ্নটি খুব পুরানো এবং গত 7 বছরে অনেক কিছুই পরিবর্তন করা হয়েছে। থ্রেড সুরক্ষার জন্য নতুন প্রোগ্রামিং কনস্ট্রাক্টস চালু করা হয়েছে।
আপনি synchronied
ব্লকের পরিবর্তে উন্নত সম্মতিযুক্ত API ব্যবহার করে থ্রেড সুরক্ষা অর্জন করতে পারেন । এই ডকুমেন্টেশন পৃষ্ঠাটি থ্রেড সুরক্ষা অর্জনের জন্য ভাল প্রোগ্রামিং কনস্ট্রাক্টস সরবরাহ করে।
লক অবজেক্টস লকিং আইডিয়ামগুলিকে সমর্থন করে যা অনেকগুলি সমবর্তী অ্যাপ্লিকেশনকে সহজতর করে।
এক্সিকিউটাররা থ্রেড চালু এবং পরিচালনা করার জন্য একটি উচ্চ-স্তরের এপিআই সংজ্ঞায়িত করে। Java.util.concurrent দ্বারা প্রদত্ত এক্সিকিউটর বাস্তবায়ন বৃহত-স্কেল অ্যাপ্লিকেশনগুলির জন্য উপযুক্ত থ্রেড পুল পরিচালনা সরবরাহ করে।
সমকালীন সংগ্রহগুলি বড় আকারের ডেটা সংগ্রহগুলি পরিচালনা করা সহজ করে তোলে এবং সিঙ্ক্রোনাইজেশনের প্রয়োজনীয়তা ব্যাপকভাবে হ্রাস করতে পারে।
পারমাণবিক ভেরিয়েবলগুলির এমন বৈশিষ্ট্য রয়েছে যা সিঙ্ক্রোনাইজেশনকে হ্রাস করে এবং মেমরির ধারাবাহিকতা ত্রুটিগুলি এড়াতে সহায়তা করে।
থ্রেডলোক্যালআর্যান্ডম ( জেডিকে in এ) একাধিক থ্রেড থেকে সিউডোরান্ডম সংখ্যার দক্ষ জেনারেশন সরবরাহ করে।
সিঙ্ক্রোনাইজডের জন্য আরও ভাল প্রতিস্থাপন হ'ল রেন্টেন্টলক , যা Lock
এপিআই ব্যবহার করে
সামঞ্জস্যীকৃত পদ্ধতি এবং বিবৃতি ব্যবহার করে, তবে প্রসারিত দক্ষতার সাথে একই বুনিয়াদী আচরণ এবং শব্দার্থবিজ্ঞানের সাথে একটি প্রেরণকারী মিউচুয়াল এক্সক্লুসিভ লক ock
তালা সহ উদাহরণ:
class X {
private final ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
lock.lock(); // block until condition holds
try {
// ... method body
} finally {
lock.unlock()
}
}
}
পড়ুন java.util.concurrent এবং java.util.concurrent.atomic অন্যান্য প্রোগ্রামিং নির্মান জন্য খুব প্যাকেজ।
এই সম্পর্কিত প্রশ্নটিও দেখুন:
সাধারণভাবে এগুলি বস্তুর মনিটরের বিষয়ে স্পষ্ট হওয়া ছাড়া অন্যটি হ'ল এই বস্তুর অন্তর্নিহিত বনাম। সিঙ্ক্রোনাইজড পদ্ধতির একটি নেতিবাচক দিক যা আমি মাঝে মাঝে উপেক্ষা করা হয় তা হ'ল আপনার সাথে সিঙ্ক্রোনাইজ করার জন্য "এই" রেফারেন্সটি ব্যবহার করে একই বস্তুতে বাহ্যিক অবজেক্ট লক হওয়ার সম্ভাবনা উন্মুক্ত হয়ে যাচ্ছে। এটিতে চালিত হলে এটি খুব সূক্ষ্ম বাগ হতে পারে। কোনও অভ্যন্তরীণ সুস্পষ্ট অবজেক্ট বা অন্যান্য বিদ্যমান ক্ষেত্রে সিঙ্ক্রোনাইজ করা এই সমস্যাটি এড়াতে পারে, সম্পূর্ণভাবে সিঙ্ক্রোনাইজেশনকে encapsulating ulating
যেমন ইতিমধ্যে এখানে বলা হয়েছে সিঙ্ক্রোনাইজড ব্লকটি ব্যবহারকারী-সংজ্ঞায়িত ভেরিয়েবলটিকে লক অবজেক্ট হিসাবে ব্যবহার করতে পারে, যখন সিঙ্ক্রোনাইজড ফাংশনটি কেবল "এটি" ব্যবহার করে। এবং অবশ্যই আপনি আপনার ফাংশনের যেগুলি সিঙ্ক্রোনাইজ করা উচিত সেগুলি দিয়ে পরিচালনা করতে পারেন। তবে প্রত্যেকে বলে যে সিঙ্ক্রোনাইজড ফাংশন এবং ব্লকের মধ্যে কোনও পার্থক্য নেই যা "এই "টিকে লক অবজেক্ট হিসাবে ব্যবহার করে পুরো ফাংশনটি কভার করে। এটি সত্য নয়, পার্থক্যটি বাইট কোডে রয়েছে যা উভয় পরিস্থিতিতেই উত্পন্ন হবে। সিঙ্ক্রোনাইজড ব্লকের ব্যবহারের ক্ষেত্রে স্থানীয় ভেরিয়েবল বরাদ্দ করা উচিত যা "এটির" রেফারেন্স ধারণ করে। এবং ফলস্বরূপ আমাদের ফাংশনের জন্য কিছুটা বড় আকার থাকবে (আপনার কাছে কেবল কয়েকটি সংখ্যক ফাংশন থাকলে প্রাসঙ্গিক নয়)।
পার্থক্যটির আরও বিশদ বিবরণ আপনি এখানে পেতে পারেন: http://www.artima.com/insidejvm/ed2/threadsynchP.html
সিঙ্ক্রোনাইজড পদ্ধতির ক্ষেত্রে, লকটি কোনও অবজেক্টে অর্জিত হবে। তবে আপনি যদি সিঙ্ক্রোনাইজড ব্লকের সাথে যান তবে আপনার কাছে এমন কোনও বিষয় নির্দিষ্ট করার বিকল্প রয়েছে যার উপর দিয়ে লকটি অর্জিত হবে।
উদাহরণ:
Class Example {
String test = "abc";
// lock will be acquired on String test object.
synchronized (test) {
// do something
}
lock will be acquired on Example Object
public synchronized void testMethod() {
// do some thing
}
}
আমি জানি এটি একটি পুরানো প্রশ্ন, তবে আমার প্রতিক্রিয়াগুলি এখানে দ্রুত পড়ার সাথে আমি সত্যিই কাউকে উল্লেখ করতে দেখিনি যে কোনও সময় কোনও synchronized
পদ্ধতিতে ভুল লক হতে পারে ।
অনুশীলনে জাভা কনকুরન્સી থেকে (পৃষ্ঠা 72২):
public class ListHelper<E> {
public List<E> list = Collections.syncrhonizedList(new ArrayList<>());
...
public syncrhonized boolean putIfAbsent(E x) {
boolean absent = !list.contains(x);
if(absent) {
list.add(x);
}
return absent;
}
উপরের কোডটিতে থ্রেড-সেফ থাকার উপস্থিতি রয়েছে। তবে বাস্তবে তা হয় না। এক্ষেত্রে ক্লাসের নির্দেশে লকটি পাওয়া যায়। তবে, তালিকার পক্ষে অন্য থ্রেডটি সেই পদ্ধতিটি ব্যবহার না করে সংশোধন করা সম্ভব । সঠিক পন্থাটি ব্যবহার করা হবে
public boolean putIfAbsent(E x) {
synchronized(list) {
boolean absent = !list.contains(x);
if(absent) {
list.add(x);
}
return absent;
}
}
উপরের কোড ব্লক হবে সকল লিপি সংশোধন করতে চেষ্টা তালিকা তালিকা পরিবর্তন সিঙ্ক্রোনাইজ ব্লক সম্পন্ন করেছে পর্যন্ত থেকে।
List
করা পারফরম্যান্সের সমস্যার দিকে নিয়ে যেতে পারে যদি এমন কোনও লগ থাকে যা অগত্যা সিঙ্ক্রোনাইজ করার প্রয়োজন হয় না
ব্যবহারিক বিষয় হিসাবে, সিঙ্ক্রোনাইজড ব্লকগুলির সাথে সিঙ্ক্রোনাইজড পদ্ধতির সুবিধা হ'ল তারা আরও বোকা প্রতিরোধী; আপনি লক করার জন্য একটি স্বেচ্ছাসেবী অবজেক্ট চয়ন করতে পারবেন না, আপনি স্ট্রিং আক্ষরিক উপর লক করা বা থ্রেডের নীচে থেকে পরিবর্তিত হয়ে যায় এমন কোনও মিউটেবল ফিল্ডের বিষয়বস্তুতে লক করা যেমন বোকা জিনিসগুলি করতে সিঙ্ক্রোনাইজড পদ্ধতি সিনট্যাক্সটির অপব্যবহার করতে পারবেন না।
অন্যদিকে, সিঙ্ক্রোনাইজড পদ্ধতিতে আপনি লকটিকে কোনও থ্রেডের অধিগ্রহণ থেকে রক্ষা করতে পারবেন না যা বস্তুর রেফারেন্স পেতে পারে।
সুতরাং পদ্ধতিগুলিতে সংশোধক হিসাবে সিঙ্ক্রোনাইজ করা আপনার গরু-বাচ্চাদেরকে আঘাত করা থেকে রক্ষা করা আরও ভাল, যখন ব্যক্তিগত চূড়ান্ত লক অবজেক্টের সাথে সমন্বয় করে সিঙ্ক্রোনাইজড ব্লকগুলি ব্যবহার করা গরু-ওকারদের থেকে আপনার নিজের কোডকে সুরক্ষিত করা আরও ভাল।
একটি জাভা স্পেসিফিকেশন সারাংশ থেকে: http://www.cs.cornell.edu/andru/javaspec/17.doc.html
সিঙ্ক্রোনাইজড স্টেটমেন্ট (.114.17) কোনও অবজেক্টের রেফারেন্স গণনা করে; এটি তখন সেই বস্তুটিতে একটি লক ক্রিয়া সম্পাদন করার চেষ্টা করে এবং লক ক্রিয়াটি সফলভাবে শেষ না হওয়া অবধি এগিয়ে যায় না। ...
একটি সিঙ্ক্রোনাইজড পদ্ধতি (§8.4.3.5) যখন অনুরোধ করা হয় তখন স্বয়ংক্রিয়ভাবে একটি লক ক্রিয়া সম্পাদন করে; লক ক্রিয়াটি সফলভাবে শেষ না হওয়া পর্যন্ত এর শরীর কার্যকর করা হয় না। যদি পদ্ধতিটি একটি উদাহরণ পদ্ধতি হয় তবে এটি যে অনুরোধটির জন্য অনুরোধ করা হয়েছিল তার সাথে যুক্ত লকটিকে লক করে রাখে (অর্থাত্, পদ্ধতিটির দেহের সঞ্চালনের সময় যে বস্তুটি এটি হিসাবে পরিচিত হবে)। যদি পদ্ধতিটি স্থিতিশীল হয় তবে এটি শ্রেণীর অবজেক্টের সাথে যুক্ত লকটি তালাবদ্ধ করে যা শ্রেণিকে প্রতিনিধিত্ব করে যেখানে পদ্ধতিটি সংজ্ঞায়িত করা হয়েছে। ...
এই বর্ণনার উপর ভিত্তি করে, আমি বলব যে পূর্ববর্তী উত্তরগুলি বেশিরভাগ সঠিক and সংজ্ঞায়িত। "
সম্পাদনা: আমি প্রথমে ভেবেছিলাম এগুলি প্রকৃত জাভা অনুচ্ছেদের উদ্ধৃতি ছিল। পরিষ্কার করা হয়েছে যে এই পৃষ্ঠাটি কেবল অনুমানের সংক্ষিপ্ত বিবরণ / ব্যাখ্যা
TLDR; synchronized
মডিফায়ার বা synchronized(this){...}
এক্সপ্রেশন ব্যবহার করবেন না তবে synchronized(myLock){...}
যেখানে myLock
কোনও ব্যক্তিগত অবজেক্টের একটি চূড়ান্ত উদাহরণ ক্ষেত্র রয়েছে।
synchronized
পদ্ধতি ঘোষণায় সংশোধক ব্যবহারের এবং synchronized(..){ }
পদ্ধতির শরীরে প্রকাশের মধ্যে পার্থক্য হ'ল :
synchronized
পরিবর্তক পদ্ধতি স্বাক্ষর উল্লিখিত
synchronized(this) { .... }
, এবংthis
স্থিতিশীল পদ্ধতিতে ঘোষিত হওয়ার সময় অবজেক্টটিকে লক হিসাবে ব্যবহার করা হয় বা স্থির পদ্ধতিতে ঘোষিত যখন ঘেরের ক্লাস হয়।synchronized(...){...}
অভিব্যক্তি আপনি করতে পারবেন
যাইহোক, ব্যবহার synchronized
পরিবর্তক বা synchronized(...) {...}
সঙ্গে this
লক বস্তু (যেমন হিসাবে synchronized(this) {...}
), একই অসুবিধা আছে। উভয় সিঙ্ক্রোনাইজ করার জন্য লক অবজেক্ট হিসাবে এটি নিজস্ব উদাহরণ ব্যবহার করে। এটি বিপজ্জনক কারণ কারণ কেবলমাত্র অবজেক্টটিই নয়, অন্য কোনও বাহ্যিক অবজেক্ট / কোড যা সেই অবজেক্টের রেফারেন্স রাখে এটি এটিকে সম্ভাব্য গুরুতর পার্শ্ব প্রতিক্রিয়া (পারফরম্যান্স অবক্ষয় এবং ডেডলকস ) সহ একটি সিঙ্ক্রোনাইজেশন লক হিসাবে ব্যবহার করতে পারে ।
সুতরাং সর্বোত্তম অনুশীলন হ'ল লক অবজেক্ট হিসাবে নয় বরং এই অবজেক্টের ব্যক্তিগত কোনও লক অবজেক্ট হিসাবে একযোগে পরিবর্তনকারী synchronized
বা synchronized(...)
অভিব্যক্তি ব্যবহার করা this
। উদাহরণ স্বরূপ:
public class MyService {
private final lock = new Object();
public void doThis() {
synchronized(lock) {
// do code that requires synchronous execution
}
}
public void doThat() {
synchronized(lock) {
// do code that requires synchronous execution
}
}
}
আপনি একাধিক লক অবজেক্টগুলিও ব্যবহার করতে পারেন তবে এটি নেস্টেড ব্যবহারের সময় ডেডলকগুলিতে না আসে তা নিশ্চিত করার জন্য বিশেষ যত্ন নেওয়া দরকার।
public class MyService {
private final lock1 = new Object();
private final lock2 = new Object();
public void doThis() {
synchronized(lock1) {
synchronized(lock2) {
// code here is guaranteed not to be executes at the same time
// as the synchronized code in doThat() and doMore().
}
}
public void doThat() {
synchronized(lock1) {
// code here is guaranteed not to be executes at the same time
// as the synchronized code in doThis().
// doMore() may execute concurrently
}
}
public void doMore() {
synchronized(lock2) {
// code here is guaranteed not to be executes at the same time
// as the synchronized code in doThis().
// doThat() may execute concurrently
}
}
}
আমি মনে করি এই প্রশ্নটি থ্রেড সেফ সিঙ্গলটন এবং ডাবল চেক লকিংয়ের সাথে অলস সূচনাটির মধ্যে পার্থক্য সম্পর্কে । যখন আমি কিছু নির্দিষ্ট সিঙ্গলটন প্রয়োগ করতে পারি তখন আমি সবসময় এই নিবন্ধটি উল্লেখ করি।
ভাল, এটি একটি থ্রেড সেফ সিঙ্গলটন :
// Java program to create Thread Safe
// Singleton class
public class GFG
{
// private instance, so that it can be
// accessed by only by getInstance() method
private static GFG instance;
private GFG()
{
// private constructor
}
//synchronized method to control simultaneous access
synchronized public static GFG getInstance()
{
if (instance == null)
{
// if instance is null, initialize
instance = new GFG();
}
return instance;
}
}
পেশাদাররা:
অলস সূচনা সম্ভব।
এটি থ্রেড নিরাপদ।
কনস:
- getInstance () পদ্ধতিটি সিঙ্ক্রোনাইজ করা হয়েছে যাতে এটি ধীর পারফরম্যান্সের কারণ হিসাবে একাধিক থ্রেড এটি একসাথে অ্যাক্সেস করতে পারে না।
এটি ডাবল চেক লকিংয়ের সাথে একটি অলস সূচনা :
// Java code to explain double check locking
public class GFG
{
// private instance, so that it can be
// accessed by only by getInstance() method
private static GFG instance;
private GFG()
{
// private constructor
}
public static GFG getInstance()
{
if (instance == null)
{
//synchronized block to remove overhead
synchronized (GFG.class)
{
if(instance==null)
{
// if instance is null, initialize
instance = new GFG();
}
}
}
return instance;
}
}
পেশাদাররা:
অলস সূচনা সম্ভব।
এটি থ্রেডও নিরাপদ।
সিঙ্ক্রোনাইজড কীওয়ার্ডের কারণে পারফরম্যান্স হ্রাস পেয়েছে।
কনস:
প্রথমবার, এটি কর্মক্ষমতা প্রভাবিত করতে পারে।
হিসাবে কনস। ডাবল চেক লকিং পদ্ধতিটি বহনযোগ্য, যাতে এটি উচ্চ কার্যকারিতা মাল্টি-থ্রেডযুক্ত অ্যাপ্লিকেশনগুলির জন্য ব্যবহার করা যায়।
আরও তথ্যের জন্য দয়া করে এই নিবন্ধটি দেখুন:
https://www.geeksforgeeks.org/java-singleton-design-pattern-practices-examples/
থ্রেডের সাথে সিঙ্ক্রোনাইজ হচ্ছে। 1) এটি কোনও কাজ করে না এমন থ্রেডে সিঙ্ক্রোনাইজড (এটি) কখনও ব্যবহার করবেন না। (এটি) এর সাথে সিঙ্ক্রোনাইজ করা বর্তমান থ্রেডটিকে লকিং থ্রেড অবজেক্ট হিসাবে ব্যবহার করে। যেহেতু প্রতিটি থ্রেড অন্যান্য থ্রেডের থেকে পৃথক, তাই সিঙ্ক্রোনাইজেশনের কোনও সমন্বয় নেই। 2) কোডের পরীক্ষাগুলি দেখায় যে একটি ম্যাকের জাভা 1.6-এ পদ্ধতি সিঙ্ক্রোনাইজেশন কাজ করে না। 3) সিঙ্ক্রোনাইজড (লকওবিজে) যেখানে লকওবজ এটিতে সিঙ্ক্রোনাইজ করা সমস্ত থ্রেডের একটি সাধারণ ভাগ করা বস্তু কাজ করবে। 4) পুনরায় সরবরাহকারী লক.লক () এবং .নলক () কাজ। এর জন্য জাভা টিউটোরিয়াল দেখুন।
নিম্নলিখিত কোড এই পয়েন্টগুলি দেখায়। এটিতে থ্রেড-সেফ ভেক্টরও রয়েছে যা অ্যারেলিস্টের পরিবর্তে প্রতিস্থাপিত হবে, এটি দেখানোর জন্য যে কোনও ভেক্টরের সাথে যুক্ত অনেকগুলি থ্রেড কোনও তথ্য হারাবে না, আর অ্যারেলিস্টের সাথে একই তথ্য হারাতে পারে। 0) বর্তমান কোড জাতিগত অবস্থার কারণে তথ্যের ক্ষয় দেখায় ক) বর্তমানের লেবেলযুক্ত একটি লাইন মন্তব্য করুন এবং তার উপরে একটি লাইনটি আপত্তিহীন করুন, তারপরে চালান, পদ্ধতিটি ডেটা হারায় তবে এটি হওয়া উচিত নয়। খ) বিপরীত পদক্ষেপ এ, পরিস্থিতি বি এবং // শেষ ব্লক}। তারপরে কোনও ফলাফলের ক্ষতি না হওয়া ফলাফল দেখতে দৌড়ে গ) মন্তব্য করুন বি, অস্বাস্থ্যকর সি চালান, সিঙ্ক্রোনাইজ করা দেখুন (এটি) ডেটা হারায়, যেমন প্রত্যাশা করা হয়েছিল। সমস্ত প্রকারের সম্পূর্ণ করার সময় নেই, আশা করি এটি সাহায্য করবে। যদি (এটি), বা পদ্ধতি সিঙ্ক্রোনাইজেশনে সিঙ্ক্রোনাইজ হয় তবে দয়া করে জাভা এবং ওএসের কোন সংস্করণ আপনি পরীক্ষা করেছেন তা উল্লেখ করুন। ধন্যবাদ.
import java.util.*;
/** RaceCondition - Shows that when multiple threads compete for resources
thread one may grab the resource expecting to update a particular
area but is removed from the CPU before finishing. Thread one still
points to that resource. Then thread two grabs that resource and
completes the update. Then thread one gets to complete the update,
which over writes thread two's work.
DEMO: 1) Run as is - see missing counts from race condition, Run severa times, values change
2) Uncomment "synchronized(countLock){ }" - see counts work
Synchronized creates a lock on that block of code, no other threads can
execute code within a block that another thread has a lock.
3) Comment ArrayList, unComment Vector - See no loss in collection
Vectors work like ArrayList, but Vectors are "Thread Safe"
May use this code as long as attribution to the author remains intact.
/mf
*/
public class RaceCondition {
private ArrayList<Integer> raceList = new ArrayList<Integer>(); // simple add(#)
// private Vector<Integer> raceList = new Vector<Integer>(); // simple add(#)
private String countLock="lock"; // Object use for locking the raceCount
private int raceCount = 0; // simple add 1 to this counter
private int MAX = 10000; // Do this 10,000 times
private int NUM_THREADS = 100; // Create 100 threads
public static void main(String [] args) {
new RaceCondition();
}
public RaceCondition() {
ArrayList<Thread> arT = new ArrayList<Thread>();
// Create thread objects, add them to an array list
for( int i=0; i<NUM_THREADS; i++){
Thread rt = new RaceThread( ); // i );
arT.add( rt );
}
// Start all object at once.
for( Thread rt : arT ){
rt.start();
}
// Wait for all threads to finish before we can print totals created by threads
for( int i=0; i<NUM_THREADS; i++){
try { arT.get(i).join(); }
catch( InterruptedException ie ) { System.out.println("Interrupted thread "+i); }
}
// All threads finished, print the summary information.
// (Try to print this informaiton without the join loop above)
System.out.printf("\nRace condition, should have %,d. Really have %,d in array, and count of %,d.\n",
MAX*NUM_THREADS, raceList.size(), raceCount );
System.out.printf("Array lost %,d. Count lost %,d\n",
MAX*NUM_THREADS-raceList.size(), MAX*NUM_THREADS-raceCount );
} // end RaceCondition constructor
class RaceThread extends Thread {
public void run() {
for ( int i=0; i<MAX; i++){
try {
update( i );
} // These catches show when one thread steps on another's values
catch( ArrayIndexOutOfBoundsException ai ){ System.out.print("A"); }
catch( OutOfMemoryError oome ) { System.out.print("O"); }
}
}
// so we don't lose counts, need to synchronize on some object, not primitive
// Created "countLock" to show how this can work.
// Comment out the synchronized and ending {, see that we lose counts.
// public synchronized void update(int i){ // use A
public void update(int i){ // remove this when adding A
// synchronized(countLock){ // or B
// synchronized(this){ // or C
raceCount = raceCount + 1;
raceList.add( i ); // use Vector
// } // end block for B or C
} // end update
} // end RaceThread inner class
} // end RaceCondition outter class