سؤال

لدي طريقة سيتم استخدامها لإرسال البريد الإلكتروني. أرغب في قفل هذه الطريقة حتى لا يتمكن مؤشر ترابط واحد فقط من وقت لكل وقت وتجمع الباقي بشكل متزامن. هل يجب علي مزامنة الطريقة أو استخدام spring @transactional spection_required؟

في طبقة خدمتي

 //each time use new thread to send out email
  public  void sendThroughSMTP(List<String> emails,String subject,String content){

            //each time will open and sent through port 25.  dont u think this will caused too many threads spawned?
            BlastEmailThread blastEmailThread = new BlastEmailThread(emails,subject,content);

            blastEmailThread.start();


}
هل كانت مفيدة؟

المحلول

لماذا لا تجعل الطريقة الآمنة مؤهلة من خلال عدم استخدام أي أشياء على مستوى المثيل؟

ومع ذلك ، لا أرى كيف تناسب إدارة معاملات الربيع هنا. أعني أن الربيع يوفر القليل من مديري المعاملات ، أي DataSourceTransactionManager, JtaTransactionManager, HibernateTransactionManager كل هذا يتعلق باستمرار قاعدة البيانات. ما الذي ستقوم بتكوينه لهذا البريد الإلكتروني إرسال؟

أعتقد ، أولاً ، يجب أن تظهر لنا لماذا تقلق بشأن سلامة الخيط في المقام الأول. على الأرجح ترغب في أن ترينا بعض قصاصة التعليمات البرمجية ذات الصلة أو شيء من هذا القبيل. ثم قد نكون قادرين على اقتراح شيء ما.

إضافة

عندما تقوم بتفريغ مؤشر ترابط لكل مكالمة لتلك الطريقة وعدم استخدام أي شيء من الحالة ، فلماذا تريد جعل الطريقة synchronized. إن جعل الطريقة متزامنة لن يحد من عدد مؤشرات الترابط بأي شكل من الأشكال. قد تكون هناك فرصة قبل بدء سلسلة رسائل جديدة ، ربما يكون مؤشر الترابط السابق قد أنهى العمل ، بسبب التزامن. قد تصبح عملية التفريخ الخيط أبطأ.

ومع ذلك ، يجب أن تذهب مع هذا حتى تكتشف أن هناك بالفعل العديد من المواضيع التي تعمل وتخرج من الذاكرة. وإذا كنت تريد حقًا معالجة ذلك قبل الوقت ، فيجب عليك اختيار بعض آلية الحظر ، شيء مثل إشارة.

نصائح أخرى

هناك احتمال آخر يتمثل في استخدام قوائم انتظار JMS ووضع رمز إرسال البريد الإلكتروني في حبة تعتمد على الرسائل (أو من خلال الربيع JMS). يمكنك بعد ذلك استخدام خادم التطبيق الخاص بك للتحكم في عدد الحالات المتزامنة من MDB الخاص بك سيتم استخدامها وتفوق رسائل البريد الإلكتروني الصادرة على هذا النحو.

في SPING 3.0 ، يمكنك استخدام التعليق التوضيحي ASYNC للقيام بتنفيذ المهمة ، لذلك سيتم تنفيذ طريقتك لاحقًا ويتم إرجاع الطريقة مباشرة دون انتظار إرسال البريد الإلكتروني.

@Async
public  void sendThroughSMTP(List<String> emails,String subject,String content){
//Send emails here, you can directly send lots of email
}

ثم في سياق التطبيق ، تحدد ولا تنس إضافة XMLNS لمخطط المهام.

إذا كنت ترغب في تأخير التنفيذ لفترة معينة من الوقت ، فيمكنك استخدام التعليقات التوضيحية التي تم تحديدها إلى طريقتك.

يمكن العثور على مزيد من البرنامج التعليمي حول async و scheduled هنا:

http://blog.springsource.com/2010/01/05/task-scheduling-simplifications-in-spring-3-0/

لست متأكدًا مما إذا كان يجيب على سؤالك ، ولكن بدلاً من إنشاء موضوع جديد لكل بريد وبدء استدعاء ، يمكن أن يكون لديك المنفذ أو ExecutorService كعضو في فصلك ، كطفة يمكنك استخدام أ Threadpoolexecutor بحجم تجمع 1. ستؤدي طريقة SendMail إلى تقديم RunNables إلى المنفذ.

SpringTransActional غير صحيح تمامًا المستخدمة في حالتك. أفضل رهان هو استخدام طريقة متزامنة وإضافة بعض تجميع مؤشرات الترابط إذا كانت الطريقة التي تسمىها مئات الوقت. لكني أعتقد أنك لا تحتاج إلى تجمع الموضوع هنا.

إذا كنت تستخدم مؤشر ترابط لإرسال بريد إلكتروني للانفجار ، فما هي النقطة التي تتم مزامنة الطريقة؟ إذا استدعت عملية واحدة طريقتك وأرسلت بريدًا إلكترونيًا ، فستقوم عملية أخرى بالاتصال بك حتى أول عملية إرسال بريد إلكتروني لا تنتهي بعد.

إذا كنت تعتزم خنق عملية إرسال البريد الإلكتروني ، فأنت بحاجة إلى إجراء قائمة انتظار (مجموعة) وحماية المجموعة باستخدام كتلة المزامنة. قم بإنشاء عملية أخرى لمراقبة قائمة الانتظار هذه ، إذا كان هناك عنصر واحد في قائمة الانتظار ، وقم ببثه وإرسال بريد إلكتروني للانفجار ، ثم انتظر حتى إرسال عملية البريد الإلكتروني إلى الانتهاء وتحقق مرة أخرى من قائمة الانتظار ، إذا كان هناك أي عنصر ، فاستمر في إرسال عملية البريد الإلكتروني. إذا لم يكن هناك عنصر في قائمة الانتظار ، فقم بإجراء نوم لخيط الشاشة لبعض الوقت ، في حين ينتهي وقت النوم ، تحقق من قائمة الانتظار مرة أخرى.

اجعل خدمتك أ singleton و أضف synchronized لطريقتك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top