كيفية إنشاء مؤشر ترابط الذي يعمل في كل مرة يتم تشغيل التطبيق

StackOverflow https://stackoverflow.com/questions/1403755

سؤال

تحرير:أنا الآن متأكد أن المشكلة متعلقة while (true) حلقة تحمل كل الأوامر الأخرى ولقد علق بها تطبيق ينشر دون تعلق الاستثناء.أنا لست متأكدا كم هو مهم لكن ServletContextListener تنفيذ يبدو مثل هذا:

public class BidPushService implements ServletContextListener{

public void contextInitialized(ServletContextEvent sce) {   
//Some init code not relevant, omitted for clarity
      BidPushThread t= new BidPushThread();
      t.setServletContext(sce.getServletContext());
      t.run();
}

حتى الآن الموضوع هو تشغيل عندما يتم نشر التطبيق ولكن لأن while حلقة وعلق ليس له معنى حقيقي.

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

حاليا انا تنفيذ ServletContextListener واجهة وأنا استدعائها عند تحميل التطبيق.في القيام ببعض الصيانة الأشياء بداية الخيط التي ورثتها من java.lang.Thread.

هنا هو بلدي حيث تبدأ المشكلة (أو هكذا أعتقد).في بلدي run() طريقة لدي

while (true) {
    //some code which doesn't put the thread to sleep ever
}

عند محاولة نشر بلدي التطبيق على الخادم أحصل على java.util.concurrent.TimeOutException.ما الخطأ الذي فعلته ؟

لا يمكن أن لدي موضوع وهو دائما يعمل ؟ عندما تمت إزالة التطبيق هذا الموضوع توقفت المقابلة الحدث في بلدي ServletContextListener.

أنا حقا بحاجة إلى شيء أن تحافظ على التحقق من الانتظار دون تأخير.

شكرا جزيلا على أي مساعدة!

تحرير:هذا هو تتبع المكدس

GlassFish: deploy is failing=
    java.util.concurrent.TimeoutException
    at java.util.concurrent.FutureTask$Sync.innerGet(Unknown Source)
    at java.util.concurrent.FutureTask.get(Unknown Source)
    at com.sun.enterprise.jst.server.sunappsrv.SunAppServerBehaviour.publishDeployedDirectory(SunAppServerBehaviour.java:710)
    at com.sun.enterprise.jst.server.sunappsrv.SunAppServerBehaviour.publishModuleForGlassFishV3(SunAppServerBehaviour.java:569)
    at com.sun.enterprise.jst.server.sunappsrv.SunAppServerBehaviour.publishModule(SunAppServerBehaviour.java:266)
    at org.eclipse.wst.server.core.model.ServerBehaviourDelegate.publishModule(ServerBehaviourDelegate.java:948)
    at org.eclipse.wst.server.core.model.ServerBehaviourDelegate.publishModules(ServerBehaviourDelegate.java:1038)
    at org.eclipse.wst.server.core.model.ServerBehaviourDelegate.publish(ServerBehaviourDelegate.java:872)
    at org.eclipse.wst.server.core.model.ServerBehaviourDelegate.publish(ServerBehaviourDelegate.java:708)
    at org.eclipse.wst.server.core.internal.Server.publishImpl(Server.java:2690)
    at org.eclipse.wst.server.core.internal.Server$PublishJob.run(Server.java:272)
    at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)

قانون بلدي:

public class BidPushThread extends Thread {
    private ServletContext sc=null;
    @Override
    public void run() {
        if (sc!=null){
            final Map<String, List<AsyncContext>> aucWatchers = (Map<String, List<AsyncContext>>) sc.getAttribute("aucWatchers");
            BlockingQueue<Bid> aucBids = (BlockingQueue<Bid>) sc.getAttribute("aucBids");

              Executor bidExecutor = Executors.newCachedThreadPool(); 
              final Executor watcherExecutor = Executors.newCachedThreadPool();
              while(true)
              {  
                 try // There are unpublished new bid events.
                 {
                    final Bid bid = aucBids.take();
                    bidExecutor.execute(new Runnable(){
                       public void run() {
                          List<AsyncContext> watchers = aucWatchers.get(bid.getAuctionId()); 
                          for(final AsyncContext aCtx : watchers)
                          {
                             watcherExecutor.execute(new Runnable(){
                                public void run() {
                                   // publish a new bid event to a watcher
                                   try {
                                    aCtx.getResponse().getWriter().print("A new bid on the item was placed. The current price "+bid.getBid()+" , next bid price is "+(bid.getBid()+1));
                                } catch (IOException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                                };
                             });
                          }                           
                       }
                    });
                 } catch(InterruptedException e){}
              }

        }
    }
    public void setServletContext(ServletContext sc){
        this.sc=sc;
    }
}

آسف على التنسيق الفوضى ولكن حياتي "المسافة البادئة كود 4 مساحات" فقط لا يعمل بالنسبة لي تحرير:قراءة حول 'BlockingQueue' و تنفيذه, ولكن أنا لا يزال الحصول على نفس استثناء و تتبع المكدس.تغيير التعليمات البرمجية أعلاه تعكس استخدام 'BlockingQueue'

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

المحلول

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

لبدء موضوع يجب استدعاء الأسلوب البداية، وليس طريقة التشغيل.

public void contextInitialized(ServletContextEvent sce) {   
//Some init code not relevant, omitted for clarity
  BidPushThread t= new BidPushThread();
  t.setServletContext(sce.getServletContext());
  t.start();// run();
}

نصائح أخرى

setDaemon

موجز:

  • يصادف هذا الموضوع إما الخيط الخفي أو مستخدم الموضوع.على آلة جافا الافتراضية مخارج عندما فقط المواضيع تشغيل كل شيطان المواضيع.
  • هذا الأسلوب يجب أن يسمى قبل بدء تشغيل مؤشر الترابط.
  • هذا الأسلوب الأول يدعو checkAccess الطريقة في هذا الموضوع
    مع أي حجج.وهذا قد يؤدي في رمي SecurityException (في
    الترابط الحالي).

المواضيع

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

وهذه ستكون فكرة سيئة للغاية. كنت يسبب الحمل CPU 100٪ من دون سبب وجيه.

والحل الصحيح هو على الارجح لمنع ترابط عند قائمة الانتظار فارغ. ويتم تنفيذ هذه مسلي مع BlockingQueue.

Can't I have a thread which is always running? When the app is removed, 
that thread is stopped by the corresponding event in my ServletContextListener.

و"يتم إيقاف هذا موضوع"؟ كيف؟ ليس هناك شرط إنهاء في حين الخاص بك (الحقيقية) {...} حلقة. كيف حالك وقف ذلك؟ هل تستخدم طريقة Thread.stop ()؟ وهذا هو غير آمن وإهمال في طريق العودة في جافا 1.1

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

إذا توفر شرط الخروج للحلقة (مثل InterruptedException أو متقلبة "stopNow" منطقية)، يمكنك تجنب هذه المشكلة.

ونلقي نظرة على java.langThread.setDaemon () الأسلوب، قد حان ما تحتاجه

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