代码之家  ›  专栏  ›  技术社区  ›  Asha Joshi

在Wicket应用程序中并发运行计时器

  •  0
  • Asha Joshi  · 技术社区  · 9 年前

    可以在wicket应用程序中并发运行计时器线程吗? 下面是我正在尝试做的示例代码。 在收到消息时,我想添加一些延迟,因此我正在运行计时器,但当我启动计时器时,主线程停止,在计时器运行期间,我没有收到任何其他消息。 可以和主线程并行运行计时器吗?谢谢

    public class Test extends WebPage{
        private Queue<String> msgQueue;
        Test(){
            msgQueue = new ConcurrentLinkedQueue<String>();
            add( new WebSocketBehavior() {      
    
            @Override
            protected void onMessage(WebSocketRequestHandler handler,
                        TextMessage message) {
                super.onMessage(handler, message);
                handleMessage(handler,message);
            }
    
        private void handleMessage(WebSocketRequestHandler handler, TextMessage msg){
            msgQueue.add(msg.getText());
            Timer timer = new Timer();
            Application application = getApplication();
            timer.schedule( new TimerTask() {
                @Override
                public void run() {
                    if (!Application.exists()) {
                        ThreadContext.setApplication(application);
                    }
                    System.out.println(getApplication());
                }
            }, 5000);
        }
    }´
    

    我正在使用java.io。在使用ScheduledThreadPoolExecutor的以下日志中可以看到NotSerializableException异常:

        Nov 27, 2016 8:19:10 PM org.apache.wicket.serialize.java.JavaSerializer serialize
        SEVERE: Error serializing object class Test [object=[Page class = Test, id = 0, render count = 1]]
        org.apache.wicket.core.util.objects.checker.CheckingObjectOutputStream$ObjectCheckException: The object type is not Serializable!
        A problem occurred while checking object with type: java.util.concurrent.ScheduledThreadPoolExecutor
    
            private final java.util.concurrent.ScheduledExecutorService Test.scheduler [class=java.util.concurrent.ScheduledThreadPoolExecutor] <----- field that is causing the problem
            at org.apache.wicket.core.util.objects.checker.CheckingObjectOutputStream.internalCheck(CheckingObjectOutputStream.java:362)
            at org.apache.wicket.core.util.objects.checker.CheckingObjectOutputStream.check(CheckingObjectOutputStream.java:341)
            at org.apache.wicket.core.util.objects.checker.CheckingObjectOutputStream.checkFields(CheckingObjectOutputStream.java:605)
            at org.apache.wicket.core.util.objects.checker.CheckingObjectOutputStream.internalCheck(CheckingObjectOutputStream.java:541)
            at org.apache.wicket.core.util.objects.checker.CheckingObjectOutputStream.check(CheckingObjectOutputStream.java:341)
            at org.apache.wicket.core.util.objects.checker.CheckingObjectOutputStream.writeObjectOverride(CheckingObjectOutputStream.java:673)
            at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
            at org.apache.wicket.serialize.java.JavaSerializer$SerializationCheckerObjectOutputStream.writeObjectOverride(JavaSerializer.java:267)
            at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
            at org.apache.wicket.serialize.java.JavaSerializer.serialize(JavaSerializer.java:78)
            at org.apache.wicket.pageStore.AbstractPageStore.serializePage(AbstractPageStore.java:133)
            at org.apache.wicket.pageStore.DefaultPageStore.createSerializedPage(DefaultPageStore.java:281)
            at org.apache.wicket.pageStore.DefaultPageStore.storePage(DefaultPageStore.java:61)
            at org.apache.wicket.page.PageStoreManager$PersistentRequestAdapter.storeTouchedPages(PageStoreManager.java:403)
            at org.apache.wicket.page.RequestAdapter.commitRequest(RequestAdapter.java:193)
            at org.apache.wicket.page.AbstractPageManager.commitRequest(AbstractPageManager.java:76)
            at org.apache.wicket.page.PageManagerDecorator.commitRequest(PageManagerDecorator.java:74)
            at org.apache.wicket.page.PageAccessSynchronizer$2.commitRequest(PageAccessSynchronizer.java:270)
            at org.apache.wicket.protocol.ws.api.AbstractWebSocketProcessor$1.onDetach(AbstractWebSocketProcessor.java:297)
            at org.apache.wicket.request.cycle.RequestCycleListenerCollection$3.notify(RequestCycleListenerCollection.java:105)
            at org.apache.wicket.request.cycle.RequestCycleListenerCollection$3.notify(RequestCycleListenerCollection.java:101)
            at org.apache.wicket.util.listener.ListenerCollection$1.notify(ListenerCollection.java:120)
            at org.apache.wicket.util.listener.ListenerCollection.reversedNotify(ListenerCollection.java:144)
            at org.apache.wicket.util.listener.ListenerCollection.reversedNotifyIgnoringExceptions(ListenerCollection.java:113)
            at org.apache.wicket.request.cycle.RequestCycleListenerCollection.onDetach(RequestCycleListenerCollection.java:100)
            at org.apache.wicket.request.cycle.RequestCycle.onDetach(RequestCycle.java:649)
            at org.apache.wicket.request.cycle.RequestCycle.detach(RequestCycle.java:594)
            at org.apache.wicket.request.cycle.RequestCycle.processRequestAndDetach(RequestCycle.java:297)
            at org.apache.wicket.protocol.ws.api.AbstractWebSocketProcessor.broadcastMessage(AbstractWebSocketProcessor.java:257)
            at org.apache.wicket.protocol.ws.api.AbstractWebSocketProcessor.onConnect(AbstractWebSocketProcessor.java:175)
            at org.apache.wicket.protocol.ws.javax.JavaxWebSocketProcessor.<init>(JavaxWebSocketProcessor.java:48)
            at org.apache.wicket.protocol.ws.javax.WicketEndpoint.onOpen(WicketEndpoint.java:58)
            at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:129)
            at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:629)
            at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
            at java.lang.Thread.run(Thread.java:745)
        Caused by: java.io.NotSerializableException: java.util.concurrent.ScheduledThreadPoolExecutor
            at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
            at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
            at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
            at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
            at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
            at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
            at org.apache.wicket.serialize.java.JavaSerializer$SerializationCheckerObjectOutputStream.writeObjectOverride(JavaSerializer.java:256)
    
    2 回复  |  直到 9 年前
        1
  •  2
  •   martin-g    9 年前

    TL;DR:将调度程序移动到应用程序中。java和公开API来调度任务。无论如何,每个页面都不需要调度程序。

    有关更多详细信息,请阅读本文: 看见 http://wicketinaction.com/2014/07/working-with-background-jobs/

        2
  •  1
  •   Vasu    9 年前

    你可以使用 ScheduledExecutorService 对于调度程序任务(在单独的线程中运行),如下所示,带有内联注释:

    public class Test extends WebPage{
    
      //Initialise ScheduledExecutorService thread pool
      private final ScheduledExecutorService scheduler =
                     Executors.newScheduledThreadPool(1);
    
        private Queue<String> msgQueue;
            Test(){
                msgQueue = new ConcurrentLinkedQueue<String>();
                add( new WebSocketBehavior() {      
    
                @Override
                protected void onMessage(WebSocketRequestHandler handler,
                            TextMessage message) {
                    super.onMessage(handler, message);
                    handleMessage(handler,message);
                }
    
            private void handleMessage(WebSocketRequestHandler handler,
                                                        TextMessage msg){
                msgQueue.add(msg.getText());
                Timer timer = new Timer();
                final Application application = getApplication();
    
                //Implement Runnable which runs in sep. Thread
                Runnable runnable = () -> {
                    if (!Application.exists()) {
                        ThreadContext.setApplication(application);
                    }
                };
    
                //Start the scheduler Now which runs for every 5 seconds
                ScheduledFuture<V> timer = scheduler.schedule(runnable, 5000, TimeUnit.SECONDS);
                //you can check timer.isDone()
            }
        }
    
        private static void enhancedLoop(int[] numbers) {
            //add your code
        }
    

    你可以看看 here 为了了解更多 ScheduleExecutorService .