2011-09-28 11 views
9

से जावा सिंक्रनाइज़ विधि का उपयोग करें मेरे पास एक जावा क्लास है जिसमें कुछ (निजी स्थैतिक) सिंक्रनाइज़ विधियां हैं जिन्हें मैं देशी कोड से भी कॉल करना चाहता हूं। कुछ उदाहरण कोड के साथ इसे और अधिक स्पष्ट हो जाता है मैं क्या मतलब हैदेशी कोड

public class SomeClass { 
    private static synchronized void method() { 
    //do something that needs synchronization 
    } 
} 

और संबद्ध मूल कोड (C++)

void someFunction(JNIEnv * env) { 
    jclass someClass = env->findClass("SomeClass"); 
    jmethodID methodId = env->GetStaticMethodID(jclass, "method", "()V"); 
    env->MonitorEnter(jclass); // <--- IS THIS NEEDED/ALLOWED 
    env->CallStaticVoidMethod(jclass, methodId); 
    env->MonitorExit(jclass); // <--- IS THIS NEEDED/ALLOWED 
} 

तो अगर मैं MonitorEnter/MonitorExit, या यदि कॉल करने की आवश्यकता है कि मैं क्या सोच रहा हूँ विधि सिंक्रनाइज़ेशन कुछClass.method() पर सिंक्रनाइज़ विशेषता द्वारा पहले ही लागू किया गया है। मुझे कोड को फिर से लिखने में बहुत दिलचस्पी नहीं है। मैं इसके चारों ओर काम करने के लिए कुछ समाधानों के बारे में सोच सकता हूं, लेकिन मुझे मूलभूत कोड से सिंक्रनाइज़ विधि के रूप में व्यवहार करने में दिलचस्पी है।

उत्तर

6

जावा भाषा विशिष्टता के अनुभाग 8.4.3.6 synchronized Methods का कहना है कि विधि सिंक्रनाइज़ किए गए विधि को घोषित करने के तरीके के समान सिंक्रनाइज़ ब्लॉक जोड़ने के समान प्रभाव पड़ता है।

+0

धन्यवाद! यह देखते हुए कि इन्हें एक ही प्रभाव के लिए निर्दिष्ट किया गया है, मैं मानता हूं कि वे एक ही बाइट कोड उत्पन्न करते हैं, इसलिए मॉनिटरइंटर/मॉनिटरएक्सिट की आवश्यकता नहीं है/अनावश्यक है। –

0

यदि आप के मालिक हैं SomeClass तुम सिर्फ

public class SomeClass { 
private static synchronized void method() { 
    //do something that needs synchronization 
    } 

private static void synchronizedMethod() { 
    method(); 
    } 
} 

कर सकते हैं और सिर्फ सी से synchronizedMethod() फोन ++।

+0

निश्चित रूप से, यह विकल्पों में से एक है। जैसा कि मैंने कहा था, हालांकि, मुझे कोड को फिर से लिखने में बहुत दिलचस्पी नहीं है। मैं समझना चाहता हूं कि क्या हो रहा है। –

3

नहीं, स्पष्ट MonitorEnter/MonitorExit की आवश्यकता नहीं है। The JNI guide के अनुसार,

... जावा प्रोग्रामिंग भाषा में सिंक्रनाइज़ेशन संरचनाओं को व्यक्त करना बेहतर है। यदि, उदाहरण के लिए, एक स्थैतिक मूल विधि को अपनी परिभाषित कक्षा से जुड़े मॉनीटर में प्रवेश करने की आवश्यकता होती है, तो आपको मूल कोड में जेएनआई-स्तरीय मॉनिटर सिंक्रनाइज़ेशन करने के विरोध में एक स्थिर सिंक्रनाइज़ मूल विधि को परिभाषित करना चाहिए।

हालांकि मूल कोड से एक जावा विधि बुला (और इसके विपरीत नहीं) सीधे कल्पना में चर्चा नहीं कर रहा है की अपने मामले, विपरीत या तो कहा नहीं है, इसलिए मैं ग्रहण करेंगे कि यह काम करता इसी तरह।

+0

धन्यवाद। मुझे पहले यह जानकारी मिली थी, लेकिन जैसा कि यह विपरीत दिशा है, मैं इतना निश्चित नहीं हूं। यदि सिंक्रनाइज़ विधि विधि() {सिंक्रनाइज़ (यह) {विधि निकाय}} जैसी किसी चीज़ में संकलित की जाती है तो मुझे कोई समस्या नहीं होगी। मुझे यकीन नहीं है कि इसके लिए बाइट कोड जेनरेट किया गया है, और जेनी कॉल के लिए एंट्री पॉइंट वास्तव में क्या है। –

+0

@Eric Moors: यह सुनिश्चित करने के लिए कि यह वही बाइट कोड है, बाइट कोड का निरीक्षण करने के अलावा कोई अन्य तरीका नहीं है। लेकिन मैं लगभग शर्त लगाता हूं कि यह है। –