2

現在、割り込み可能なジョブを実装しようとしています。仕事は大体こんな感じ

public abstract class Job
{
    private boolean interruptFlag;

    public boolean isinterrupted()
    {
        return interruptFlag;
    }

    public void interrupt()
    {
        interruptFlag = true;
    }

    public abstract void execute();

}

public class JobImplementation extends Job
{
    public void execute
    {
        for (int i = 0; i < 10; i++)
        {
            doSomethingWithI(i);
            if (interruptedFlag())
            {
                break;
            }
        }
    }
}

一部のコントローラーが interrupt() メソッドを呼び出したときに、実行本体の for ループを中断したいと思います。

しかし、私はこれをすべての JobImplementaionClass のすべての for ループに実装したくありません。

私がやりたいのは、実行中のコードと条件をパラメーターとして取得する抽象 Job クラスのメソッドのようなものです。

何かのようなもの

protected void doFor(conditionCode, executionCode)
{
    for (conditionCode)
    {
         executeCode();
         if (isInterrupted())
             break;
    }
}

JobImplementation クラスは通常の for ループを使用しませんが、次のようになります。

public void execute()
{
    doFor({int i = 0; i < 10; i++}, {doSomethingWithI(i)})
}

このようにして、実際の JobImplementation から制御の詳細を隠そうとします。新しい JobImplementation を作成するとき、この doFor ループを使用して、気にせずに中断することができます。

これを実際に実装する方法を知っている人はいますか? これは可能ですか?

4

5 に答える 5

1
public abstract class LoopJob extends Job {
    private int iterations;

    public LoopJob(int iterations) {
        this.iterations = iterations;
    }

    @Override public void execute() {
        for (int i = 0; i < iterations && !isInterrupted(); ++i) {
            executeIteration(i);
        }
    }

    protected abstract void executeIteration(int i);
}

このようなもの?そのような柔軟性が本当に必要な場合は、初期化子、条件、およびインクリメンターを追加の抽象メソッドに入れ、ループ変数を派生クラスのメンバーに変えることで、より柔軟にすることができます。

于 2013-05-23T10:18:57.503 に答える
0

申し訳ありませんが、長い間お待ちください。まだ興味がある人のために、私は今、うまくいくと思われる解決策を実装する時間を見つけました.

public abstract class Job
{
    AtomicBoolean isInterrupted = new AtomicBoolean(false);

    public boolean isinterrupted()
    {
        return interruptFlag;
    }

    public void interrupt()
    {
        isInterrupted.set(true);
    }

    public abstract void execute();

    public void doLoop(Callable<Boolean> callable, Runnable runnable) 
    {
    try
        {
            while (true)
        {
            ExecutorService executor = Executors.newSingleThreadExecutor();
            Future<Boolean> result = executor.submit(callable);
                if (!result.get())
                break;
                executor.submit(runnable);
            if (isInterrupted.get())
                break;

                        // TestCode. simulates some serious code given 
                        // by the the runnable
               try
               {
                   Thread.sleep(1000);
               } 
                               catch (InterruptedException e)
               {
                           // do Something
               }
        }
    }
    catch (InterruptedException e)
    {
            // do Something
    } 
    catch (ExecutionException e)
    {
            // do Something
    }
}


}

そして実装サブクラスは行きます

public class JobImplementation extends Job
{
public void execute()
{
    Thread interruptor= new Thread(new Interrupter(this));
    interruptor.start();
    final Iterator<String> it = collection.iterator();
    doLoop(new Callable<Boolean>() 
           {
               public Boolean call() throws Exception 
               {
                   return it.hasNext();
               }}, 
           new Runnable() 
           {
               public void run()
               {
                   System.out.println(it.next());
               }
           });
}


public class Interrupter implements Runnable 
    {
        LoopUserClass user;
        public Interrupter(LoopUserClass user)
        {
            this.user = user;
        }

        public void run() 
        {
            try
            {
                Thread.sleep(5000);
            } 
            catch (InterruptedException e)
            {
                // do Something
            }
            user.interrupt();
        }
}

    public static void main(String[] args)
    {
        LoopUserClass user = new LoopUserClass();       
        for (int i = 0; i < 10; i++)
        {
            user.collection.add("testString" + i);
        }
        user.execute();
    }
}

実装するサブクラスは doLoop(Callable, Runnable) メソッドを使用するようになりました。doLoop メソッドは、無限に実行されます。Callable はブレーク条件を計算します。ランナブルは、ループ本体の実際のコードを実行します。その後、doLoop は isInterrupted-flag が true であるかどうかをチェックし、その場合は中断します。

doLoop のスリープはテスト用です。スリープを実行可能にすると、うまくいかないように見えましたが、pffft. ただtestCode ...同じことが内部クラスInterruptorにも当てはまります。割り込みがまったく別の場所から来ることを想像してください。

doLoop のユーザーは Callable および Runnable-Object を作成する必要があるため、この概念はまだ少し醜いように見えます。クロージャが Java に実装されるまでは、おそらく変わらないでしょう。

于 2013-05-30T08:52:49.350 に答える
0

1 回の繰り返しで構成されるExecutors.singleThreadedExecutorwhere you tasks を使用することをお勧めします。submit制御クラスでは、タスクを適切な回数サブミットすることを確認するだけでよく、中断は をシャットダウンするだけで処理されますExecutorService

于 2013-05-23T10:17:50.700 に答える
0

for-loop を -loop にwhile変えることができます

public void execute() {
    int i = 0;
    while (!isInterrupted() && i < 10) {
        // do something with i
        i++;
    }
}
于 2013-05-23T10:17:36.883 に答える