سؤال

لدي مجموعة من الإجراءات التي يجب تنفيذها على التوالي حتى يتم تنفيذ جميعها، أو يتم استيفاء شرط معين. إليك الرمز الأساسي الذي يحتاج إلى تنفيذه حتى يتم استيفاء شرط:

public boolean search()
{
    robot.go();

    robot.spin();

    //etc - around 8 more similar commands (each takes around 2 seconds)
    return false; //didn't find what it was looking for
}

حتى الآن، الطريقة الوحيدة التي فكرت بها في القيام بما أردت هذا:

public boolean search()
{
    robot.go(false);
    while(robot.isMoving())
    {
        if(thingFound())
        {
            robot.stop()
            return true;
        }
        Thread.yield();
    }

    robot.spin(false);
    while(robot.isMoving())
    {
        if(thingFound())
        {
            robot.stop()
            return true;
        }
        Thread.yield();
    }


    //etc - around 8 more similar commands
    return false; //didn't find what it was looking for
}

ال false المعلمة إلى go() و spin() يشير إلى أنه يجب عليهم العودة على الفور، مما يسمح بفحص الشرط. ومع ذلك، فإن هذا النهج يضربني كأعلى إلى حد ما، حيث يجب تكرار نفس كتلة التعليمات البرمجية 10 مرات. هل يمكن تحقيق ذلك بشكل أكثر كفاءة مع الاستثناءات أو المواضيع المتزامنة؟

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

المحلول

بناء على جوناثان ليفلر إجابه:
يمكنك استخدام runnable كما مؤشر إلى الأوامر

private final Runnable going = new Runnable() {
    @Override
    public void run() {
        robot.go(false);
    }
});

private final Runnable spinning = new Runnable {
    @Override
    public void run() {
        robot.spin(false);
    }
});

// other commands 


private boolean isFoundAfter(Runnable command)
{
    command.run();
    while (robot.isMoving())
    {
        if (thingFound())
        {
            robot.stop()
            return true;
        }
        Thread.yield();
    }
    return false;
}

public boolean search()
{
    if (isFoundAfter(going)) return true;

    if (isFoundAfter(spinning)) return true;   

    //etc - around 8 more similar commands
    return false; //didn't find what it was looking for
}


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

...

private boolean executeSearch(Runnable... commands)
{
    for (Runnable cmd : commands) {
        if (isFoundAfter(cmd)) return true;
    }
    return false; //didn't find what it was looking for
}

public boolean search() {
    return executeSearch(going, spinning /* around 8 more similar commands */);
}

نصائح أخرى

لست متأكدا لماذا تستخدم Thread.yield() - هل هناك مواضيع أخرى تنفذ أنك لم تذكر؟ أو ربما أخطأت المشكلة.

أعتقد أنه ربما يمكن أن يعمل نمط الأمر هنا. سيكون لديك RobotCommand واجهة مع execute الطريقة، وتنفيذ RobotCommand لكل نوع أمر (اذهب، تدور، إلخ). ثم يمكنك بناء RobotAlgorithm ك List من RobotCommand, ، ولها طريقة executeRobotAlgorithm التي تكررت على القائمة، استدعاء execute على كل RobotCommand والتحقق من نتيجة thingFound() بعد كل واحد.

يحرر - أوه، أعتقد أنني أحصل عليه. يفعل go و spin انطلاق الخيوط التي تغير حالة الروبوت، أو شيء من هذا القبيل؟

تحرير 2. - استجابة لتعليقك، يبدو أن المشكلة هنا هي أنك بحاجة إلى أن تكون قادرا على العودة على الفور إذا وجد الروبوت ما يبحث عنه، ولكن go, spin, ، لن تقوم أوامر وما إلى ذلك الآن، وتحتاج إلى القدرة على الاستمرار في تنفيذ أوامر جديدة في هذه الأثناء. إذن ما قد أقوم به هنا هو اثنين من الخيوط - واحد سيكون موضوع "منفذ" من شأنه أن ينفذ الخاص بك List من RobotCommandق واحد تلو الآخر، وخيط "مراقب" الذي سوف ينام ومرارا وتكرارا (تحقق thingFound()). إذا thingFound() صحيح من أي وقت مضى ثم يمكنك إيقاف الروبوت الخاص بك وكذلك مؤشر ترابط المنفذ، أو إذا وصل المنفذ إلى النهاية من قبل thingFound() صحيح ثم يمكن أن يشير إلى مثل هذا (إذا لزم الأمر).

من الواضح أن الحلقة التي يمكن تعبئتها في وظيفتها الخاصة:

private boolean isFound()
{
    while (robot.isMoving())
    {
        if (thingFound())
        {
            robot.stop()
            return true;
        }
        Thread.yield();
    }
    return false;
}

public boolean search()
{
    robot.go(false);
    if (isFound()) return true;

    robot.spin(false);
    if (isFound()) return true;   

    //etc - around 8 more similar commands
    return false; //didn't find what it was looking for
}

(لا أمانع إذا تم تقسيم الشرط على سطرين؛ ربما أفعل ذلك في رمز الإنتاج.)

مبرمج Java أفضل مما يمكنني إخبارك ما إذا كان يمكنك نقل "الإجراءات" حولها (المؤشرات إلى الوظائف، من حيث البرمجة C). أظن أنك تستطيع، لكنني لا أعرف بناء الجملة والقواعد. ال دليل يبدو أنه لا يمكنك (حوالي 2004، على أي حال).

يمكن للروبوت استخدام كائن حالة للإشارة إلى وحدة التحكم التي تكتمل بعض المهمة الفرعية أو دخلت حالة جديدة:

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/condition.html.

مثيرة للاهتمام، للبيئة التي يمكن أن تستخدمها و إعلام () و انتظر() بدلا من حالة أكثر مرونة. يمكن أن تنتظر جهاز التحكم () حتى يقرر الروبوت إطلاق سراحه بالإخطار ().

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