سؤال

لدي تطبيق أرجغ يخزن قائمة بالأشياء. عندما ينقر المستخدمون على زر

أريد أن أدفع عمليا في كل كائن في القائمة، ثم مرة واحدة كاملة، رسم بياني النتائج في JPanel. لقد كنت أحاول Swingworker، Callable & Runnable للقيام بالمعالجة، ولكن بغض النظر عن ما أقوم به، مع معالجة القائمة (والتي يمكن أن تستغرق ما يصل إلى بضع دقائق، كما هو الحال في IO)، يتم حبس واجهة المستخدم الرسومية.

لدي شعور بأنها ربما الطريقة التي أسميها الخيوط أو أي شيء ما، أو هل يمكن أن تفعل مع وظيفة الرسوم البيانية؟ هذا ليس خيوط لأنه سريع جدا.

يجب أن أقوم بمراحل المعالجة الخاصة بالتعامل معها أيضا، فما هي أفضل طريقة لضمان انتظرت الثانية في الأول؟ لقد استخدمت الانضمام ()، ثم

while(x.isAlive())  
{  
        Thread.sleep(1000);  
}

لمحاولة التأكد من ذلك، لكنني قلقة من ذلك قد يكون سبب مشكلتي أيضا.

لقد كنت أتطلع في كل مكان لبعض المؤشرات، لكن بما أنني لا أستطيع أن أجد أي متأكد من أنني أفعل شيئا غبيا هنا.

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

المحلول

المشكلة هي، مهمتك التشغيلية الطويلة تقوم بحظر الخيط الذي يحافظ على استجابة واجهة المستخدم الرسومية.

ما ستحتاج إليه هو وضع المهمة الجارية الطويلة على مؤشر ترابط آخر.

بعض الطرق الشائعة للقيام بذلك تستخدم أجهزة ضبط الوقت أو SwingWorker.

ال دروس جافا لديك الكثير من المعلومات المتعلقة بهذه الأشياء في درسهم في التزامن.

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

هنا هو تنفيذ عينة من SwingWorker لحالتك:

public class YourTaskSwingWorkerSwingWorker extends SwingWorker<List<Object>, Void> {
    private List<Object> list
    public YourClassSwingWorker(List<Object> theOriginalList){
        list = theOriginalList;
    }

    @Override
    public List<Object> doInBackground() {
        // Do the first opperation on the list
        // Do the second opperation on the list

        return list;
    }

    @Override
    public void done() {
        // Update the GUI with the updated list.
    }
}

لاستخدام هذا الرمز، عند تشغيل الحدث تعديل القائمة، قم بإنشاء جديد SwingWorker وأخبرها أن تبدأ.

نصائح أخرى

أنت لا تعود موضوع التأرجح بشكل صحيح. أدرك أنك تستخدم Callable / Runnable ولكني أظن أنك لا تفعل ذلك بشكل صحيح (على الرغم من أنك لم تنشر كود كاف لمعرفة بالتأكيد).

سيكون الهيكل الأساسي:

swingMethod() { // Okay, this is a button callback, we now own the swing thread
    Thread t=new Thread(new ActuallyDoStuff());
    t.start();
}

public class ActuallyDoStuff() implements Runnable {
    public void run() {
        // this is where you actually do the work
    }
}

هذا فقط قبالة رأس رأسي، لكنني أظن أنك لا تفعل الخيط. بدلا من ذلك استدعاء طريقة التشغيل مباشرة، أو تقوم بعمل شيء آخر في الطريقة الأولى التي تقفزها ( مثل thread.join). لا أحد من هذه سوف تحرير مؤشر ترابط البديل. يجب أن تعود الطريقة الأولى بسرعة، يمكن أن تستغرق طريقة التشغيل () طالما تريد.

إذا كنت تقوم بعمل ترابط. في الطريقة الأولى، فلن يتم إرجاع الخيط إلى النظام!

تحرير: (تحرير الثاني في الواقع) أفكر في التحدث إلى المشكلة التي تشعر بها بالفعل - قد ترغب في التفكير أكثر من حيث نظام نموذج / عرض / وحدة تحكم. تعد الرمز الذي تكتبه هو وحدة التحكم (يتم اعتبار العرض عموما أن تكون المكونات على الشاشة - عرض / وحدة تحكم مرتبطة بإحكام شديدة جدا).

عندما يحصل جهاز التحكم الخاص بك على الحدث، يجب أن يمر العمل في النموذج الخاص بك. وجهة النظر هي ثم الخروج من الصورة. لا تنتظر النموذج، فقد انتهى.

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

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

لا أستطيع التحدث حقا إلى نموذج مؤشر الترابط سوينغ، ولكن:

يجب أن أقوم بمراحل المعالجة الخاصة بالتعامل معها أيضا، فما هي أفضل طريقة لضمان انتظرت الثانية في الأول؟

لهذا النوع من الوظائف، أقترح عليك إنشاء مؤشرات ترابط عاملين، وتضمين وسيط JMS. تقديم العمل إلى مؤلمين من خلال تمرير الرسائل في قوائم انتظار JMS التي يقرؤها من. خيط Gui الخاص بك مجاني في فحص قوائم الانتظار لتحديد متى يحدث العمل ويمثل حالة اللعب في UI.

كان الحل لمشكلتي مزيجا من إجابات JJNGUY و Bill K، حتى شكرا جزيلا لذلك اللاعبين. كنت بحاجة لاستخدام الخيوط داخل مبيعات الأرجوحة مثل هذا:

public class Worker extends SwingWorker<Void, Void>   
{  
    private List<Object> list;  
    public YourClassSwingWorker(List<Object> theOriginalList){  
        list = theOriginalList;  
    }

    @Override
    public List<Object> doInBackground() {
        Thread t = new Thread(new ProcessorThread(list));  
        t.start();
    }

    @Override
    public void done() {
        // draw graph on GUI
    }
}  
class ProcessorThread implements Runnable {  
    //do lots of IO stuff  
    Thread t2 = new Thread(new SecondProcess());
    t2.start();  
}

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

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