مقدمة
في الآونة الأخيرة ، واجهت مشكلة adadlock عند بدء مشروع الربيع. عند استخدام JSTACK للحصول على مكدس مؤشر الترابط ، يمكنك أن ترى أن ترابطين لهما مسدود:
عملية الحل:
رمز المصدر لـ DefaultSingletonBeanRegistry.getSingleton() كما يلي. يمكنك أن ترى أن هذه الطريقة تتطلب قفل SingletOnobjects.
الكود المصدري لـ xxx.subject.cace.cache.datalocalcacheinit.afterPropertiesset كما يلي:
يمكنك أن ترى أنه عند تهيئة هذه الفاصوليا ، ستبدأ مؤشر الترابط واتصل طريقة initData() لحبة أخرى لتحميل البيانات من قاعدة البيانات. سيتم اعتبار تهيئة حبة datalocalcacheinit كاملة بعد تحميل البيانات.
من المكدس أعلاه ، يمكننا أن نرى أنه عندما تقوم حاوية الزنبرك بتهيئة الفول ، فإنها ستقفل كائن SingletOnobjects ؛ نفتح موضوعًا في طريقة afterPropertiesSet() ، والتي ستؤدي في النهاية إلى تشغيل الربيع لتحميل فول آخر. لم يطلق الخيط الأول (الخيط الرئيسي الذي يهيئة Spring) القفل ، والخيط الثاني (الخيط الذي يتم فتحه بمفرده) يحتاج أيضًا إلى الحصول على قفل كائن SingletOnobjects ، والذي يسبب Deadlock. الظاهرة الموضحة هي أن حاوية الزنبرك عالقة هناك ولا يمكنها إكمال تهيئة جميع الفاصوليا.
دعنا نلقي نظرة على مثال ، يشبه إلى حد كبير الكود الفعلي في مشروعنا. يستدعي Firstbean الطريقة في Confighelper:
الطبقة العامة FirstBean تنفذ initializationBean {Override public void بعد propertiesset () رمي الاستثناء {system.out.println ("First Bean يتم تهيئة ....") ؛ قائمة انتظار blockingqueue = جديد arrayblockingqueue (10) ؛ Thread Thread = New Thread () {Override public void run () {confighelper.dosomething () ؛ Queue.Add (1) ؛ }} ؛ thread.start () ؛ queue.take () ؛ System.out.println ("First Get Data ....") ؛ }} رمز confighelper كما يلي: احصل على فول آخر من خلال Beanfactory
الطبقة العامة confighelper تنفذ beanfactoryaware {private static beanfactory factory ؛ Override public void setBeanfactory (beanfactory beanfactory) يلقي beansexception {this.factory = beanfactory ؛ } public static void dosomething () {SecondBean Bean = (SecondBean) factory.getBean ("Second") ؛ bean.say () ؛ }} رمز SecondBean بسيط على النحو التالي:
الفئة العامة الثانية {public void say () {system.out.println ("SecondBean ...") ؛ }}ملف تكوين الربيع ورمز بدء التشغيل كما يلي. يمكنك العثور على مسدود عند الجري:
<؟ XSI: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <noft "> </ban> id = </beans> الفئة العامة الرئيسية {public static void main (string [] args) {ApplicationContext context = new FileSystemSmlapPlicationContext (عند تهيئة الربيع ، إذا بدأنا الخيط لاكتساب الحبة في بعض نقاط التمديد التي توفرها الربيع (Beanfactoryaware/Oirtivipean ، إلخ) ، فسيتم سد الحاوية. نظرًا لأن Spring يهيئة حبوب Singleton (معظم الفاصوليا المفردة) ستضيف أقفال. إذا لم يتم إصدار القفل عند تهيئة حبة واحدة ، وتشغيل مؤشر ترابط آخر حبة تحميل الربيع مرة أخرى ، سيظهر Deadlock.
حل المشكلة أعلاه أمر بسيط: يعتمد FirstBean بشكل منطقي على Confighelper و SecondBean ، لكننا لا نعرض العلاقة المنطقية في الربيع. عندما يقوم Spring بتهيئة FirstBean ، أدخل afterPropertiesSet() . ستؤدي هذه الطريقة إلى تشغيل تحميل الفاصوليا الأخرى عند تشغيل الخيط. نحتاج فقط إلى إظهار تبعية الربيع والسماح بحمل الربيع Confighelper و SecondBean أولاً.
<bean id = "config" تعتمد على = "second"> </boan> <bean id = "first" تعتمد على = "config"> </bean> <bean id = "second"> </bean>
لخص
ما سبق هو المحتوى الكامل لهذه المقالة. آمل أن يكون لمحتوى هذه المقالة قيمة مرجعية معينة لدراسة أو عمل الجميع. إذا كان لديك أي أسئلة ، فيمكنك ترك رسالة للتواصل. شكرا لك على دعمك إلى wulin.com.