Spring@Async簡単学習


spring referenceを見ているとspringの中の非同期taskのパッケージが見えて面白かったので試してみました.
簡単に言えば、springはjavaのTaskExecutorをカプセル化してpojoのように使用することができますが、実際にはTaskExecutorService(私が間違っていなければjavaにはこのクラスでしょう)を直接使用することもできます.もちろん自分で実現することもできますが、springはThreadPoolTaskExecutorのようなクラスを提供しています.なぜ使用しないのでしょうか.もちろん、より重要なのは、プロファイルにThreadPoolTaskExecutorのbeanを宣言することに相当する簡便な方法を提供することです.次は実験を始めます.
1まずcontext.xmlでいくつかの宣言を行い、ThreadPoolTaskExecutorを構成し、anotation drivenを使用します.
<context:component-scan base-package="test" />
<task:executor id="myExecutor" pool-size="2" />
<task:annotation-driven executor="myExecutor" />

2,非同期実行が必要なコードを記述する.
@Async
	public Future do()  {
		........		
		return new AsyncResult(...);
	}

 この場所は私を驚かせた場所です.ここでは2つのことをするだけで、annotateという方法は@Asyncであり、この方法をFutureオブジェクトに戻す(この方法が値を返す必要がなければ、これも必要なく、voidを返す必要がある).また,実際にパラメータを伝達する必要がある場合は,他の方法のように伝達することもできる.ドキュメントによれば、これを行うと、このメソッドを呼び出すと直接戻りますが、body部分が非同期で実行される必要があります.私たちがしなければならないのは、Future.get()で待つだけです.不思議でしょ?
3,次は他のbeanのように,callerとcalleeはcontextで得られ,通常のメソッドを呼び出すように呼び出せばよい.
4、いくつかの問題
    もちろんいくつかの問題にも遭遇しました.そうしないと、上に簡単に羅列したように、ドキュメントのcopyを直接持ってきたほうがいいです.
    a,最初は,この非同期メソッドをmain()(mainはcontextを起動するために使用される)に直接置いたが,このメソッドは実際に非同期で実行されていないことが分かった.私はいくつかの資料を探して、やり方が私とあまり違わないことに気づいた.この簡単な応用springは問題ないでしょう?springはこの方法のためにproxyを生成するに違いないと思います.それは私たちのためにthread、futureを生成することをたくさんしただけです.springがmainがいるクラスのためにproxyを生成できないか、少なくともこのような非同期方法のためにproxyを生成できないかという問題があるかもしれません.私はこの方法を新しいクラスに移してから、やはり成功しました.もちろんもっとdetailの原因があるかもしれません.
    b、aを押してやったらhappyです.しかし、プログラムが実行されると、このhappyはゆっくりとなくなりました.プログラムが長い間終わっていないことに気づいたからです.また時間が経ってもまだ終わっていません(eclipseで実行していますが、console状態からプログラムがまだ実行されていることがわかります).このような状況は、その2つの非同期の任務が終わっていないからだと思います.jconsoleで調べてみると、やはりその非同期スレッドwaitでmainスレッドが終了していることがわかりました.鬱陶しい.私たちが自分で書いたthreadであれば、タスクが完了すると自然に止まりますが、springが私たちのために生成したスレッドを管理しなければなりません.これはあまりにも不快です.しかし、幸いなことに処理する方法がある.contextによってthreadPoolTaskExecutorが得られ、destroyメソッドが呼び出されます.