0

要求オブジェクトに追加された JMS オブジェクトがあり、doPost() メソッドで、オブジェクトの get メソッドが呼び出されて、応答としてクライアントに継続的に送信される現在のトピック データを取得します。

同時に別のユーザー要求で、doPost() メソッドに表示されず、get メッセージが呼び出されているか、呼び出しから空/null 文字列を受け取っています。

同時リクエスト/ユーザーに対してメソッドをレスポンシブにする方法。

デバッグ時: Eclipse でデバッグしているときに、両方のスレッドが getMessage データを交互に受け取ることがあります。

<jms:listener-container connection-factory="connectionFactory" task-executor="jmsTaskExecutor" destination-type="topic" concurrency="5">    
    <jms:listener destination="abc.topic" ref="abc" method="receive" />     
</jms:listener-container>

<bean name="jmsTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="corePoolSize" value="2"/>
    <property name="maxPoolSize" value="50"/>       
    <property name="threadNamePrefix" value="some-queue-thread"/>
</bean>

<bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="connectionFactory"/>
    <property name="pubSubDomain" value="true"/>
</bean>


@Component("abc")
public class abc {

private String msg;

public synchronized void receive(String msg){       
    this.msg = msg;     
}


public synchronized String getMessage(){        
    return msg;     
}
}

@Component
@Controller
public class ForwardController extends ServletForwardingController
{   
@Autowired
abc topicObject;

@Override   
@RequestMapping("/xyzPath")
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {       
        request.setAttribute("autowired", topicObject);
        request.getRequestDispatcher("/xyz").forward(request, response);
    }        
return null;
}   

@WebServlet("/xyz")
public class xyz extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) {

abc topicObject =  request.getAttribute("autowired");

while(true){        
    System.out.println("start"+Thread.currentThread.getId());
    String msg = topicObject.getMessage();
    response.getWriter.write(msg);
    System.out.println("stop"+Thread.currentThread.getId());
  }
 }
}

topicObject.getMessage()を同時に呼び出す正しい方法は何ですか

4

1 に答える 1

0

@Async アノテーションを削除します。何を意図していたのかはわかりませんが、そうではありません。

Javadocから:

ただし、戻り値の型は または のいずれかに制限されvoidますFuture

そしてSpringフレームワークのドキュメントから:

メソッドに @Async アノテーションを付けて、そのメソッドの呼び出しが非同期で行われるようにすることができます。つまり、呼び出し元は呼び出し時にすぐに戻り、Spring TaskExecutor に送信されたタスクでメソッドの実際の実行が行われます。

つまり、@Async を使用すると、コードはすぐには実行されず、後で別のスレッドで実行されますが、すぐに戻ります。したがって、あなたgetMessageはサポートされていない戻り値の型を提供し、未定義の動作につながります(あなたの場合はランダムです)。

メソッドのreceive場合、これは への割り当てを延期するため、これも必要ではありませんmessage

解決策:両方の @Async アノテーションを削除し、両方のメソッドを作成synchronizedして、変数への変更を正しく発行し、messageすべてのスレッドで表示できるようにします。

于 2015-01-09T06:45:17.670 に答える