Frage

Ich habe eine Methode, die verwendet wird E-Mail zu versenden. Ich möchte diese Methode sperren, damit nur ein Thread kann es pro Zeit und den Rest Pool accses gleichzeitig auf. Sollte ich die Methode oder den Einsatz von Feder @Transactional PROPAGATION_REQUIRED synchronisiert?

in meiner Dienstschicht

 //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();


}
War es hilfreich?

Lösung

Warum macht das Verfahren nicht Thread-sicher durch keine Instanz-Ebene Dinge verwenden?

Allerdings sehe ich nicht, wie Spring Transaction Management hier paßt. Ich meine Frühling wenige Transaktionsmanager bietet, das heißt DataSourceTransactionManager, JtaTransactionManager, HibernateTransactionManager all dies ist über Datenbankpersistenz. Was werden Sie für diese E-Mail konfigurieren auszusenden?

ich glaube, zuerst sollten Sie uns zeigen, warum Sie die Thread-Sicherheit in erster Linie darum kümmern. Wahrscheinlich möchten Sie uns einige relevante Code-Schnipsel oder etwas zeigen. Dann könnten wir in der Lage sein, Ihnen etwas zu suggerieren.

[Nachtrag]

Wenn Sie einen Thread für jeden Aufruf dieser Methode Laichen und nicht vom Staat mit etwas, warum wollen Sie die Methode synchronized machen. Wodurch das Verfahren nicht synchronisiert werden, die Anzahl der Fäden in keiner Weise einschränken. Es könnte sein, Chance, die vor einen neuen Thread starten, könnte vorheriger Thread die Arbeit beendet hat, weil die Synchronisation. Der Prozess einen Thread von Laich könnte langsamer gehen.

Sie sollten jedoch mit diesem gehen, bis Sie herausfinden, dass es wirklich viele Threads laufen und Sie sind aus Speicher ausgehen. Und wenn Sie wollen wirklich angehen, dass vor der Zeit, dann sollten Sie etwas blockiert Mechanismus wählen, so etwas wie Semaphore .

Andere Tipps

Eine andere Möglichkeit wäre, JMS-Warteschlangen zu verwenden und die E-Mail zu senden Code in einer Message Driven Bean (oder durch Feder JMS) zu setzen. Anschließend können Sie Ihre App-Server zu steuern, wie viele gleichzeitige Instanzen Ihrer MDB verwendet werden und Drossel die versendeten E-Mails auf diese Weise.

in Sping 3.0 können Sie @Async Annotation verwenden Aufgabenausführung zu tun, so dass Ihre Methode später ausgeführt wird, und das Verfahren zurückgeführt wird direkt ohne E-Mail für noch zu senden sind.

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

dann in Anwendungskontext Sie angeben, und vergessen Sie nicht xmlns für Aufgabe Schema hinzuzufügen.

Wenn Sie die Ausführung für bestimmte Zeit verzögern wollen, können Sie @Scheduled Anmerkung zu Ihrer Methode verwenden.

Weitere Tutorial über @Async und @Scheduled finden Sie hier:

http: // blog .springsource.com / 2010/01/05 / Task-Scheduling-Vereinfachungen-in-Feder-3-0 /

Ich bin mir nicht sicher, ob es Ihre Frage beantwortet, aber anstatt einen neuen Thread für jede Mail-Erstellung und lostelefonieren darauf konnte man eine haben Executor oder ExecutorService als Mitglied der Klasse, als Implementierung Sie ThreadPoolExecutor mit einer Poolgröße von 1. Ihre Sendmail-Methode würde dann Runnables zum Testamentsvollstrecker einreichen.

Frühling @Transactional ist nicht ganz richtig in Ihrem Fall verwendet. Die beste Wette wird mit synchorized Methode und einige Threadpooling hinzufügen, wenn Ihre Methode von Hunderten Mal aufgerufen. Aber ich denke, Sie müssen Thread-Pool nicht hier.

Wenn Sie Thread verwenden Explosion E-Mail zu senden, dann was Synchronisationspunkt des Verfahrens? wenn ein Prozess Ihre Methode und E-Mail senden nennen, andere Verfahren werden Sie Methode aufrufen, sogar das erste Senden von E-Prozess noch nicht beenden.

Wenn Sie die Absicht, den E-Mail-Sendevorgang zu drosseln, müssen Sie eine Warteschlange condider (Sammlung) und die Sammlung mit synchronize Block zu schützen. Erstellen Sie einen anderen Prozess, dass die Warteschlange zu überwachen, wenn es ein Element in der Warteschlange ist, knallen sie und Explosion E-Mail senden, dann warten Sie E-Mail-Prozess beenden, bis das Senden und prüfen Sie erneut in die Warteschlange, wenn es irgendein Element ist, weiterhin E-Mail-Prozess zu senden. Wenn kein Element in der Warteschlange, um den Monitor-Thread Schlaf für einig Stück der Zeit machen, dann, wenn Schlafzeit wieder in die Warteschlange Finish überprüfen.

Machen Sie Ihren Dienst ein singleton und fügen synchronized zu Ihrer Methode.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top