سؤال

ونظرا لx مثيل Callable<T>، كيف يمكنني تشغيل x في عملية منفصلة بحيث يمكنني إعادة توجيه الإدخال القياسي والإخراج من هذه العملية؟ على سبيل المثال، هل هناك طريقة لبناء Process من Callable؟ هناك Executor المعيار الذي يعطي السيطرة على المدخلات والمخرجات؟

و[تحديث] انه ليس من المهم أن Callable تنفيذ في عملية جديدة في مقابل موضوع جديد. ما أريده هو أن يضع المثال Callable في "تسخير"، بحيث أستطيع السيطرة على المدخل / المخرج المعياري. AFAIK، وهذا يدعو إلى عملية جديدة.

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

المحلول

وبصورة أعم:

<اقتباس فقرة>   

ونظرا مثيل العاشر من استخدام للاستدعاء المتغيرات العالمية A و B، كيف يمكنني تشغيل x مثل بالتزامن أن x يرى القيم المخصصة للA و B، بدلا من القيم "الأصلية" من A و B؟

وأفضل الجواب، لا تستخدم المتغيرات العالمية. الاعتماد على حقن أشياء من هذا القبيل. تمديد للاستدعاء وإضافة أساليب setStdIn، setStdOut (وsetStdErr إذا كنت في حاجة إليها).

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

* "الحق" يجري استخدام نمط مقبولة على نطاق واسع من حقن التبعية لتوفير اقتران فضفاضة. YMMV

وUPDATE: ردا على تعليق 1. هنا هو واجهة الجديدة:

import java.io.InputStream;
import java.io.PrintStream;
import java.util.concurrent.Callable;


public interface MyCallable<V> extends Callable<V> {
  void setStdIn(InputStream in);
  void setStdOut(PrintStream out);  
}

ووالمهام الخاصة بك قد تبدو:

import java.io.InputStream;
import java.io.PrintStream;


public class CallableTask implements MyCallable<Object> {

    private InputStream in = System.in;
    private PrintStream out = System.out;

    public void setStdIn(InputStream in) {
        this.in = in;
    }

    public void setStdOut(PrintStream out) {
        this.out = out;
    }

    public Object call() throws Exception {
        out.write(in.read());
        return null;
    }

و}

لا حاجة لعملية. أي حل (حتى واحد باستخدام العمليات) ويكاد يكون من المؤكد سوف تتطلب تغييرات رمز إلى Callables بطريقة أو بأخرى. هذا هو أبسط (مجرد استبدال System.out مع this.out).

نصائح أخرى

والمدخل / المخرج المعياري يمكن إعادة توجيه للنظام بأكمله، ولكن لست متأكدا من أنه يمكن إعادة توجيه لموضوع واحد - كنت دائما مجرد الحصول عليه من النظام. (يمكنك جعل System.out الذهاب إلى تيار آخر على الرغم من أنني قد استخدمت ذلك للقبض على آثار المكدس قبل كان هناك طريقة للحصول على أثر كسلسلة)

هل يمكن إعادة توجيه المدخل / المخرج المعياري، تشغيل للاستدعاء ثم إعادة توجيه مرة أخرى، ولكن إذا كان أي شيء آخر يستخدم System.out في حين انها توجيهها، من شأنها أن تذهب أيضا إلى الملف الجديد.

والأساليب سيكون System.setIn () وSystem.setOut () (وSystem.setErr ()) إذا كنت ترغب في السير في هذا الطريق.

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

إذا كنت لا ترغب في إزالة استخدام System.in/out/err كنت في الحظ. يمكن تعيين هذه على الصعيد العالمي مع System.set(In/Out/Err). لتكون قادرة على تيار مختلف عن المواضيع الفردية بتعيين تنفيذ يستخدم ThreadLocal للعثور على الهدف تخويل. موضوع السكان المحليين وعموما الشر، ولكن يمكن أن تكون مفيدة في حالات مؤسفة.

ومن التوضيحات، يبدو أن الملصق الأصلي لا يوجد لديه الحاجة إلى إنشاء عملية منفصلة.

وإلقاء نظرة على الطبقة ProcessBuilder، فهو يوفر لك الخيار لالتقاط المعياري وستدير العملية التي تطلق.

ويمكنك إنشاء فئة الرئيسية التي تدير للاستدعاء، ومن ثم إطلاقه كما JVM آخر مع ProcessBuilder. الطبقة الرئيسية يمكن أن تقبل اسم الفئة للاستدعاء الخاص بك كما سطر الأوامر المعلمة المدخلات وتحميل مع Class.forName () وClass.newInstance ().

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

والسؤال هو، لماذا تريد أن تفعل ذلك؟ لا تستطيع فقط تشغيل الخاص بك للاستدعاء في موضوع آخر؟ java.util.concurrent لديه بعض حمامات موضوع مفيدة، فقط لذلك.

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