Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 可中断循环_Java_Loops_Interrupt - Fatal编程技术网

Java 可中断循环

Java 可中断循环,java,loops,interrupt,Java,Loops,Interrupt,我目前正在尝试实现可中断作业。 这项工作大体上是这样的 public abstract class Job { private boolean interruptFlag; public boolean isinterrupted() { return interruptFlag; } public void interrupt() { interruptFlag = true; } publi

我目前正在尝试实现可中断作业。 这项工作大体上是这样的

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;
            }
        }
    }
}
JobImplementation类不会使用普通for循环,但是:

public void execute()
{
    doFor({int i = 0; i < 10; i++}, {doSomethingWithI(i)})
}
public void execute()
{
doFor({inti=0;i<10;i++},{doSomethingWithI(i)})
}
通过这种方式,我试图从实际的job实现中隐藏控制细节。 当我编写一个新的JobImplementation时,我可以使用这个doFor循环,并且可以在不关心它的情况下中断它


有没有人知道如何真正实现这一点?这可能吗?

您可以将-for的
循环变成
-while循环

public void execute() {
    int i = 0;
    while (!isInterrupted() && i < 10) {
        // do something with i
        i++;
    }
}
public void execute(){
int i=0;
而(!isInterrupted()&&i<10){
//和我一起做点什么
i++;
}
}

我建议使用
Executors.singleThreadedExecutor
提交只包含一次迭代的任务。在控制类中,您只需确保提交任务的次数正确,只需关闭
ExecutorService

公共抽象类LoopJob扩展作业,即可处理中断{
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);
}
私有整数迭代; 公共循环作业(整数迭代){ this.iterations=迭代次数; } @重写公共void execute(){ 对于(int i=0;i

像这样的?如果您确实需要这种灵活性,您可以通过将初始值设定项、条件和递增项放入额外的抽象方法中,将循环变量转换为派生类的成员,使其更加灵活。

前面的答案没有考虑到一件重要的事情:并发性

您应该使用类似AtomicBoolean的东西来控制中断标志(因为,此时,当某个线程“中断”您的循环时,您的循环代码可能永远不会获得新的中断状态)

我的建议是使用如下代码:

public abstract class Job
{
    private final AtomicBoolean interruptFlag = new AtomicBoolean(false);
    private final int loopCount;

    protected Job(final int loopCount) {
        this.loopCount = loopCount;
    }

    public final boolean isinterrupted()
    {
        return interruptFlag.get();
    }

    public final void interrupt()
    {
        interruptFlag.set(true);
    }

    public final void execute() {
        for (int i = 0; i < loopCount && !checkInterrupted(); i++) {
           doSomethingWithI(i);
        }
    }

    protected abstract boolean checkInterrupted();

    protected abstract void doSomethingWithI(int i);

}

public class InterruptableJob extends Job
{
    public InterruptableJob () {
         super(10);
    }

    protected final boolean checkInterrupted() {
         return isInterrupted();
    }

    protected final void doSomethingWithI(final int i) {
          .... ;
    }
}
在上面的实现中,Java运行时基本上会完全忽略测试,并且不会对性能产生影响

请注意我是如何使用AtomicBoolean来避免任何并发问题的

抱歉,等待时间太长了。 对于那些仍然感兴趣的人,我现在找到了实施一个似乎有效的解决方案的时间

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
    }
}


}
公共抽象类作业
{
AtomicBoolean isInterrupted=新的AtomicBoolean(false);
公共布尔值isinterrupted()
{
返回中断标志;
}
公共空间中断()
{
isInterrupted.set(真);
}
公共抽象void execute();
public void doLoop(Callable Callable,Runnable Runnable)
{
尝试
{
while(true)
{
ExecutorService executor=Executors.newSingleThreadExecutor();
未来结果=执行人提交(可调用);
如果(!result.get())
打破
执行人提交(可运行);
if(isInterrupted.get())
打破
//模拟给定的一些重要代码
//按规定
尝试
{
睡眠(1000);
} 
捕捉(中断异常e)
{
//做点什么
}
}
}
捕捉(中断异常e)
{
//做点什么
} 
捕获(执行例外)
{
//做点什么
}
}
}
而实现的子类

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();
    }
}
公共类作业实现扩展了作业
{
public void execute()
{
线程中断器=新线程(新中断器(this));
interruptor.start();
final Iterator it=collection.Iterator();
doLoop(新的可调用函数)
{
公共布尔调用()引发异常
{
返回它。hasNext();
}}, 
新的Runnable()
{
公开募捐
{
System.out.println(it.next());
}
});
}
公共类中断器实现可运行
{
LoopUserClass用户;
公共中断器(LoopUserClass用户)
{
this.user=用户;
}
公开募捐
{
尝试
{
睡眠(5000);
} 
捕捉(中断异常e)
{
//做点什么
}
user.interrupt();
}
}
公共静态void main(字符串[]args)
{
LoopUserClass用户=新的LoopUserClass();
对于(int i=0;i<10;i++)
{
user.collection.add(“testString”+i);
}
user.execute();
}
}
实现子类现在使用doLoop(Callable,Runnable)-方法。 doLoop方法运行了很长时间。 可调用函数计算中断条件。runnable执行循环体的实际代码。 之后,doLoop检查isInterrupted标志是否为true,并在这种情况下中断

在doLoop中睡觉只是为了测试。它似乎不起作用,如果我把睡眠变成可运行的,但pffft。只是测试代码。。。 内部类中断器也是如此。您应该想象一下,中断将完全来自其他地方


这个概念看起来仍然有点难看,因为doLoop的用户必须创建可调用和可运行的对象。在java中实现闭包之前,这一点可能不会改变。

+1,您试图实现的概念看起来不错:)看起来您正在描述一个线程!一个可以被中断的“可运行”类!你可以使用可观察的模式:正是这样,鲍勃:但我尽量避免打电话给thr
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();
    }
}