无法使用Java Streams取消预定任务列表。

huangapple go评论43阅读模式
英文:

Not able to cancel list of scheduled tasks using Java Streams

问题

我有一个实现了Runnable接口的类

 class AppThread implements Runnable {
    	String s;
    	public AppThread(String s) {
			this.s=s;
		}
		@Override
		public void run() {
			System.out.println(s);
			
		}
    }

我创建了一些任务并将它们提交给ScheduledThreadPool,等待10秒后取消了这些计划任务。

    ScheduledExecutorService s = Executors.newScheduledThreadPool(1);
	List<ScheduledFuture<?>> list = new ArrayList<>();
	
    public static void main( String... args ) throws InterruptedException
	{
		App app = new App();
		app.method("A");
		app.method("D");
		app.method("C");
		app.method("B");
		Thread.sleep(10000);
        app.cancelTasks();
	}
 public void method(String s) {
		list.add(this.s.scheduleAtFixedRate(new AppThread(s), 1, 2, TimeUnit.SECONDS));		
    }

我成功地使用list.forEach取消了任务。
Method2

    public void cancelTasks() {
    	System.out.println("Stopping Executors");
		this.list.forEach(sf -> sf.cancel(false));
    }

但是,当我尝试使用Java流来取消任务时,虽然没有异常,但任务仍然继续执行。
Method2

    public void cancelTasks() {
    	System.out.println("Stopping Executors");
		this.list.stream().map(sf -> sf.cancel(false));
    }

我仍然在努力理解流的使用,但我不明白为什么第二种方法不起作用。

英文:

I have a class implementing Runnable interface

 class AppThread implements Runnable {
    	String s;
    	public AppThread(String s) {
			this.s=s;
		}
		@Override
		public void run() {
			System.out.println(s);
			
		}
    }

I am creating few tasks and submitting to a ScheduledThreadPool and after waiting for 10 seconds cancelling the scheduled tasks.

    ScheduledExecutorService s = Executors.newScheduledThreadPool(1);
	List&lt;ScheduledFuture&lt;?&gt;&gt; list = new ArrayList&lt;&gt;();
	
    public static void main( String... args ) throws InterruptedException
	{
		App app = new App();
		app.method(&quot;A&quot;);
		app.method(&quot;D&quot;);
		app.method(&quot;C&quot;);
		app.method(&quot;B&quot;);
		Thread.sleep(10000);
        app.cancelTasks();
	}
 public void method(String s) {
		list.add(this.s.scheduleAtFixedRate(new AppThread(s), 1,2, TimeUnit.SECONDS));		
    }

I am successfully able to cancel the tasks using list.forEach
Method2

    public void cancelTasks() {
    	System.out.println(&quot;Stopping Executors&quot;);
		this.list.forEach(sf -&gt; sf.cancel(false));
    }

But when I do so using Java streams, I get not exception but the tasks still continue to execute.
Method2

    public void cancelTasks() {
    	System.out.println(&quot;Stopping Executors&quot;);
		this.list.stream().map(sf-&gt; sf.cancel(false));
    }

I am still trying to get hold of streams, but I do not understand why the second method doesn't work.

答案1

得分: 1

map是一种中间操作,除非列表被终端操作实体化,否则它不会执行任何操作。这样,你可以有效地链接许多中间流操作。这种模式也许更好地被称为惰性评估

如果你想要对每个流元素执行一个动作,并立即这样做,你需要使用foreach

因此,你的代码应该变成:

this.list.stream().forEach(sf -> sf.cancel(false));
英文:

map is an intermediate operation, which doesn't do anything at all unless the list is materialized by a terminal operation. This way, you can effectively chain quite a lot of intermediate stream operations. This pattern is maybe better known as lazy-evaluation.

If you want to execute an action on each stream element, and do so immediately, you need to use foreach.

Thus, your code should become

 this.list.stream().forEach(sf-&gt; sf.cancel(false));

huangapple
  • 本文由 发表于 2020年7月29日 15:11:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/63148184.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定