यदि कोई थ्रेड टी 1 क्लास लेवल लॉक प्राप्त करके एक विधि एम 1 में प्रवेश करता है, तो क्या इसका मतलब है कि एक और थ्रेड टी 2 ऑब्जेक्ट लेवल लॉक प्राप्त करके एक अलग विधि एम 2 नहीं चला सकता है?जावा क्लास लेवल लॉक बनाम ऑब्जेक्ट लेवल लॉक
उत्तर
नहीं, इसका मतलब यह नहीं है। "क्लास लेवल लॉक" एक अलग ऑब्जेक्ट पर एक नियमित लॉक है, अर्थात् SomeClass.class
। this
पर "ऑब्जेक्ट लेवल लॉक" लॉक।
संपादित करें:
public class SomeClass {
public synchronized static void m1() {
//do something
}
public synchronized void m2() {
//do something
}
}
और जवाब: बस के रूप में वे नीचे परिभाषित कर रहे हैं, तो एम 1 और एम 2 समवर्ती चलाया जा सकता है यकीन है कि मैं शब्दावली की अपनी समझ अनुसरण कर रहा हूँ, आप सोच रहे हैं बनाने के लिए हाँ है, एम 1 और एम 2 समवर्ती रूप से चलाया जा सकता है। यह कार्यात्मक इस के बराबर है:
public class SomeClass {
public static void m1() {
synchronized (SomeClass.class) {
//do something
}
}
public void m2() {
synchronized (this) {
//do something
}
}
}
के बाद से वे पूरी तरह से विभिन्न वस्तुओं पर सिंक्रनाइज़ कर रहे हैं, वे परस्पर अनन्य नहीं हैं।
जावा में ताले के दो प्रकार हैं:
- कक्षा स्तर
- वस्तु स्तर
स्टेटिक तरीकों के मामले में ताला हमेशा वर्ग पर लेकिन उदाहरण के मामले में चेक किया गया है ऑब्जेक्ट पर ताला हमेशा जांच की जाती है।
उदाहरण:
show1()
गैर स्थिर और show()
है स्थिर है। अब, show()
कक्षा नाम (या ऑब्जेक्ट द्वारा) और show1()
ऑब्जेक्ट द्वारा बुलाया जाता है, तो दोनों विधियों को एक साथ दो धागे तक पहुंचा जा सकता है।
class Shared{
static int x;
static synchronized void show(String s,int a){
x=a;
System.out.println("Starting in method "+s+" "+x);
try{
Thread.sleep(2000);
}
catch(Exception e){ }
System.out.println("Ending from method "+s+" "+x);
}
synchronized void show1(String s,int a){
x=a;
System.out.println("Starting show1 "+s);
try{
Thread.sleep(2000);
}
catch(Exception e){ }
System.out.println("Ending from show1 "+s);
}
}
class CustomThread extends Thread{
Shared s;
public CustomThread(Shared s,String str){
super(str);
this.s=s;
start();
}
public void run(){
Shared.show(Thread.currentThread().getName(),10);
}
}
class CustomThread1 extends Thread{
Shared s;
public CustomThread1(Shared s,String str){
super(str);
this.s=s;
start();
}
public void run(){
s.show1(Thread.currentThread().getName(),20);
}
}
public class RunSync {
public static void main(String[] args) {
Shared sh=new Shared();
CustomThread t1=new CustomThread(sh,"one");
CustomThread1 t2=new CustomThread1(sh,"two");
}
}
आउटपुट:
Starting in method one 10
Starting show1 two
Ending from method one 20
Ending from show1 two
वस्तु स्तर लॉकिंग:
वस्तु स्तर ताला तंत्र जब आप एक गैर स्थैतिक विधि या गैर स्थिर कोड ब्लॉक सिंक्रनाइज़ करना चाहते हैं ऐसी है कि केवल एक ही धागा कक्षा के दिए गए उदाहरण पर कोड ब्लॉक निष्पादित करने में सक्षम होंगे। यह आवृत्ति स्तर डेटा थ्रेड सुरक्षित करने के लिए हमेशा किया जाना चाहिए। यह नीचे के रूप में किया जा सकता है:
public class DemoClass
{
public synchronized void demoMethod(){}
}
or
public class DemoClass
{
public void demoMethod(){
synchronized (this)
{
//other thread safe code
}
}
}
or
public class DemoClass
{
private final Object lock = new Object();
public void demoMethod(){
synchronized (lock)
{
//other thread safe code
}
}
कक्षा के स्तर का ताला:
कक्षा के स्तर का ताला से अधिक थ्रेड क्रम पर सभी उपलब्ध उदाहरणों में से किसी में सिंक्रनाइज़ ब्लॉक में प्रवेश करने के लिए रोकता है। इसका अर्थ यह है कि यदि रनटाइम में डेमो क्लास के 100 उदाहरण हैं, तो केवल एक ही थ्रेड एक समय में किसी भी एक में demoMethod() निष्पादित करने में सक्षम होगा, और अन्य सभी उदाहरण अन्य थ्रेड के लिए लॉक हो जाएंगे। स्थिर डेटा थ्रेड को सुरक्षित बनाने के लिए यह हमेशा किया जाना चाहिए।
public class DemoClass
{
public synchronized static void demoMethod(){}
}
or
public class DemoClass
{
public void demoMethod(){
synchronized (DemoClass.class)
{
//other thread safe code
}
}
}
or
public class DemoClass
{
private final static Object lock = new Object();
public void demoMethod(){
synchronized (lock)
{
//other thread safe code
}
}
}
उदाहरण जावा में वस्तु और कक्षा स्तर ताले को समझने के लिए
1) ऑब्जेक्ट स्तर ताला उदाहरण
package com.test;
public class Foo implements Runnable {
@Override
public void run() {
Lock();
}
public void Lock() {
System.out.println(Thread.currentThread().getName());
synchronized(this) {
System.out.println("in block " + Thread.currentThread().getName());
System.out.println("in block " + Thread.currentThread().getName() + " end");
}
}
public static void main(String[] args) {
Foo b1 = new Foo();
Thread t1 = new Thread(b1);
Thread t2 = new Thread(b1);
Foo b2 = new Foo();
Thread t3 = new Thread(b2);
t1.setName("t1");
t2.setName("t2");
t3.setName("t3");
t1.start();
t2.start();
t3.start();
}
}
उत्पादन:
t1
t3
t2
in block t3
in block t1
in block t3 end
in block t1 end
in block t2
ध्यान दें कि थ्रेड टी 1 और टी 2 ब्लॉक के दौरान टी 3 ब्लॉक नहीं होगा। क्योंकि ताला इस वस्तु और धागा पर रखा गया है t3 अलग धागा t1 से इस वस्तु, t2 है
2) कक्षा स्तर ताला उदाहरण
वस्तु स्तर ताला में कोड, केवल Foo.class है सिंक्रनाइज़ ब्लॉक में जोड़ा गया। फू क्लास की ऑब्जेक्ट का उपयोग करके सभी थ्रेड बनाए जा रहे हैं अवरुद्ध हो जाएंगे।
package com.test;
public class Foo implements Runnable {
@Override
public void run() {
Lock();
}
public void Lock() {
System.out.println(Thread.currentThread().getName());
synchronized(Foo.class) {
System.out.println("in block " + Thread.currentThread().getName());
System.out.println("in block " + Thread.currentThread().getName() + " end");
}
}
public static void main(String[] args) {
Foo b1 = new Foo();
Thread t1 = new Thread(b1);
Thread t2 = new Thread(b1);
Foo b2 = new Foo();
Thread t3 = new Thread(b2);
t1.setName("t1");
t2.setName("t2");
t3.setName("t3");
t1.start();
t2.start();
t3.start();
}
}
उत्पादन:
t1
t3
in block t1
in block t1 end
t2
in block t3
in block t3 end
in block t2
in block t2 end
सिंक्रनाइज़ ब्लॉक एक ही धागे के लिए क्रियान्वित किया जा रहा है।
ऐसा नहीं है कि दोनों स्थिर सिंक्रनाइज़ और गैर स्थिर सिंक्रनाइज़ विधि एक साथ या समवर्ती क्योंकि वे विभिन्न वस्तु पर ताला चला सकते हैं संभव है।
कक्षा के स्तर का ताला कीवर्ड "स्टैटिक समन्वयित है, जहां वस्तु स्तर के रूप में सिंक्रनाइज़ कीवर्ड द्वारा केवल हासिल की है द्वारा हासिल की है। वस्तु स्तर ताला अलग धागा, जहां के माध्यम से संचालित करने के लिए एक ही वस्तु को प्रतिबंधित करने के हासिल की है क्योंकि किसी ऑब्जेक्ट को संचालित करने के लिए कक्षा स्तर लॉक प्राप्त किया जाता है।
श्रेणी स्तर लॉकिंग के विभिन्न तरीके: 1) सार्वजनिक वर्ग DemoClass {
public static synchronized void demoMethod(){
//dosomething
}
}
2)
सार्वजनिक वर्ग DemoClass {
public void demoMethod(){
synchronized(DemoClass.class){
//dosomething
}
}
}
3)
सार्वजनिक वर्ग DemoClass {
private final static Object lock = new Object();
public void demoMethod(){
synchronized(lock){
//dosomething
}
}
}
यह प्रश्न का उत्तर कैसे देता है? – shmosel
कक्षा के स्तर का ताला और उदाहरण के स्तर को लॉक दोनों अलग हैं। दोनों एक दूसरे को लॉक स्थिति में हस्तक्षेप नहीं करते हैं। यदि किसी वर्ग का एक उदाहरण पहले से ही थ्रेड द्वारा लॉक हो गया है तो एक और धागा उस उदाहरण के लिए लॉक नहीं हो सकता है जब तक कि पहले थ्रेड द्वारा लॉक मुक्त न हो जाए। कक्षा स्तर लॉक के लिए वही व्यवहार है।
लेकिन यदि कोई धागा कक्षा स्तर लॉक प्राप्त करता है तो दूसरा धागा इसके उदाहरण में लॉक प्राप्त कर सकता है। 1true
सभी किसी भी विराम के बिना तुरन्त मुद्रित हो जाएगी Instance2 कक्षा उदाहरण -: दोनों काम कर सकते हैं parallel.`
package lock;
class LockA implements Runnable {
@Override
public void run() {
synchronized (LockA.class) {
System.out.println("Class");
try {
Thread.sleep(60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class TestClassVsInstanceLock {
public static void main(String[] args) {
final LockA a = new LockA();
final LockA b = new LockA();
try {
Thread t = new Thread(a);
Thread t1 = new Thread() {
@Override
public void run() {
synchronized (b) {
System.out.println("Instance 1"+ currentThread().currentThread().holdsLock(b));
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t.start();
t1.start();
synchronized (a) {
System.out.println("Instance2");
Thread.sleep(10 * 1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
`
यह प्रिंट होगा।
यदि कोई थ्रेड टी 1 कक्षा स्तर लॉक प्राप्त करके एक विधि एम 1 में प्रवेश करता है, तो क्या इसका मतलब है कि एक और थ्रेड टी 2 ऑब्जेक्ट लेवल लॉक प्राप्त करके एक अलग विधि m2 नहीं चला सकता है?
ऑब्जेक्ट लेवल लॉक और क्लास लेवल लॉक अलग हैं। उपरोक्त मामले में, टी 2 ऑब्जेक्ट लेवल लॉक प्राप्त करके विधि एम 2 चला सकता है। लेकिन अगर एम 2 static synchronized
है, तो टी 2 एम 2 विधि का आह्वान नहीं कर सकता है जब तक कि टी 1 विधि एम 1 पर कक्षा स्तर लॉक जारी न करे।
यह एक ही वस्तु पर synchronized
तरीकों में से दो आमंत्रण बिछा करने के लिए संभव नहीं है। जब एक थ्रेड किसी ऑब्जेक्ट के लिए synchronized
विधि निष्पादित कर रहा है, तो अन्य सभी थ्रेड जो ऑब्जेक्ट के साथ पहले थ्रेड किए जाने तक उसी ऑब्जेक्ट ब्लॉक (निष्पादन को निलंबित) के लिए synchronized
विधियों का आह्वान करते हैं।
मान लें कि आप दो synchronized
तरीकों एम 1 और वस्तु ओ पर एम 2 है कि धागा T1 विधि एम 1 के निष्पादन के बीच में है, तो धागा टी 2, जब तक कि धागा T1 रिलीज ताला एक ही वस्तु हे पर विधि एम 2 कॉल करने के लिए इंतजार करना पड़ता है विधि एम 1 पर।
थ्रेड वर्ग के साथ जुड़े Class
वस्तु के लिए आंतरिक ताला प्राप्त कर लेता है। इस प्रकार कक्षा के static
फ़ील्ड तक पहुंच को लॉक द्वारा नियंत्रित किया जाता है जो कक्षा के किसी भी उदाहरण के लिए लॉक से अलग होता है।
मान लें कि विधि m1 static synchrnozed
है और विधि m2 भी static synchronized
है और आपके पास दो अलग-अलग ऑब्जेक्ट्स ओ 1 और ओ 2 हैं।
यदि थ्रेड टी 1 ऑब्जेक्ट ओ 1 पर विधि एम 1 के निष्पादन के मध्य में है, तो थ्रेड टी 2 को ऑब्जेक्ट ओ 2 पर कॉल विधि एम 2 तक प्रतीक्षा करना है जब तक कि विधि m1 पर थ्रेड टी 1 रिलीज लॉक न हो।
- 1. प्रॉपर्टीग्रिड ऑब्जेक्ट-लेवल
- 2. रीडरवाइटर लॉक बनाम लॉक {}
- 3. लॉक प्रश्न - 'यू' लॉक बनाम 'एक्स' लॉक
- 4. एपीआई लेवल 8
- 5. लेवल बनाम एज ट्रिगर नेटवर्क इवेंट मैकेनिज्म
- 6. ट्रांसपोर्ट-लेवल बनाम संदेश-स्तरीय सुरक्षा
- 7. Grails: एंटरप्राइज़ लेवल Grails
- 8. मल्टी लेवल xml jquery
- 9. डिवाइस वॉल्यूम लेवल
- 10. मल्टी लेवल बैश प्राप्ति
- 11. ऑडियो प्रोसेसिंग: वॉल्यूम लेवल
- 12. सी # थ्रेडिंग - लॉक ऑब्जेक्ट
- 13. ConcurrentQueue बनाम कतार + लॉक
- 14. रिकर्सिव लॉक (म्यूटेक्स) बनाम गैर-रिकर्सिव लॉक (म्यूटेक्स)
- 15. पायथन में Django मॉडल के लिए क्लास लेवल प्रॉपर्टी
- 16. एंड्रॉइड में पैकेट लेवल नेटवर्किंग
- 17. टाइप लेवल लिटलल्स - द्विआधारी फ़ंक्शन
- 18. एक्लिप्स एंड्रॉइड चेंज एपीआई लेवल
- 19. एंड्रॉइड लॉग लेवल सेट करना
- 20. जावा कंसुरेंसी: लॉक क्षमता
- 21. एप्लिकेशन बनाम कैश: लॉक तंत्र
- 22. लॉक स्टेटमेंट बनाम मॉनीटर। विधि
- 23. एक्सएचआर लेवल 2 फ़ाइल अपलोड के लिए
- 24. लॉक टेबल (लॉक टेबल द्वारा लॉक) का पता लगाने
- 25. एनएसएलॉक - लॉक लॉक लॉक करते समय बस ब्लॉक करना चाहिए?
- 26. अलगाव लेवल का उपयोग करना। स्नैपशॉट लेकिन डीबी अभी भी
- 27. मल्टी लेवल CodeFirst में शामिल है - EntityFrameWork
- 28. मल्टी-लेवल मेनू जैसे वर्डप्रेस-मेन्यू
- 29. आईओएस में मल्टी लेवल ट्री UITableView
- 30. एन लेवल चिल्ड्रन के माध्यम से इटरेटिंग
क्या होगा यदि दोनों विधियों को स्थैतिक घोषित किया गया हो? मुझे विश्वास है कि उस मामले में, दोनों पारस्परिक रूप से अनन्य हो जाएंगे, क्या यह सही है? – buch11
@ buch11: यह सही है, ऐसा लगता है कि दोनों सिंक्रनाइज़ (कुछ क्लास.क्लास) {...} 'कर रहे थे, और किसी भी जटिल क्लासलोडिंग परिदृश्य को छोड़कर, यह दोनों मामलों में एक ही वस्तु होगी। तकनीकी रूप से, क्लासलोडिंग आपको एक ही कक्षा के दो अलग "लोडिंग" की अनुमति देता है, और आप समानांतर में इस तरह के विभिन्न वर्गों में स्थिर सिंक्रनाइज़ विधियों को चला सकते हैं। लेकिन उस अजीबता को छोड़कर, यह पारस्परिक रूप से अनन्य है। –
आपको आश्चर्य हो सकता है कि एक स्थिर सिंक्रनाइज़ विधि कब लागू की जाती है, क्योंकि एक स्थिर विधि कक्षा से जुड़ी होती है, न कि ऑब्जेक्ट। इस मामले में, धागे कक्षा से जुड़े कक्षा वस्तु के लिए आंतरिक लॉक प्राप्त करता है। ** इस प्रकार कक्षा के स्थैतिक क्षेत्रों तक पहुंच को लॉक द्वारा नियंत्रित किया जाता है जो कक्षा के किसी भी उदाहरण के लिए लॉक से अलग होता है। ** [स्रोत] (https://docs.oracle.com/javase/tutorial/essential/concurrency /locksync.html) – Eduardo