From: jsimomaa Date: Thu, 14 Dec 2017 06:16:51 +0000 (+0200) Subject: Replace OrientationRestorer TimerTask usage with ScheduledExecutor X-Git-Tag: v1.43.0~136^2~659 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F20%2F1320%2F2;p=simantics%2Fplatform.git Replace OrientationRestorer TimerTask usage with ScheduledExecutor Timer can exhaust the system with TimerTask-runnables that are queued up e.g. during computer hibernate and sleep. According to documentation: If an execution is delayed for any reason (such as garbage collection or other background activity), two or more executions will occur in rapid succession to "catch up." In the long run, the frequency of execution will be exactly the reciprocal of the specified period With heavy tasks this is very bad refs #7682 Change-Id: I5a097c8bc5e1ea2a5abe30905b2a46fa8b8386f8 --- diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/OrientationRestorer.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/OrientationRestorer.java index 02cd89d9c..f2a420b12 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/OrientationRestorer.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/OrientationRestorer.java @@ -13,8 +13,9 @@ package org.simantics.g2d.participant; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; -import java.util.Timer; -import java.util.TimerTask; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import org.simantics.g2d.canvas.Hints; import org.simantics.g2d.canvas.ICanvasContext; @@ -22,8 +23,8 @@ import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant; import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; import org.simantics.g2d.canvas.impl.HintReflection.HintListener; import org.simantics.utils.datastructures.disposable.DisposeState; -import org.simantics.utils.datastructures.hints.IHintObservable; import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.datastructures.hints.IHintObservable; import org.simantics.utils.threads.IThreadWorkQueue; /** @@ -44,10 +45,10 @@ public class OrientationRestorer extends AbstractCanvasParticipant { long lastTrigger; Point2D centerPoint = new Point2D.Double(); - transient Timer timer = new Timer("Rotate restore"); + transient ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor(); transient boolean checkRotatePending = false; - TimerTask task = new TimerTask() { + Runnable task = new Runnable() { @Override public void run() { ICanvasContext ctx = getContext(); @@ -70,16 +71,24 @@ public class OrientationRestorer extends AbstractCanvasParticipant { @Override public void removedFromContext(ICanvasContext ctx) { - timer.cancel(); + timer.shutdown(); + try { + if (!timer.awaitTermination(1, TimeUnit.SECONDS)) { + timer.shutdownNow(); + } + } catch (InterruptedException e) { + // Ignore + } super.removedFromContext(ctx); } @Override public void addedToContext(ICanvasContext ctx) { super.addedToContext(ctx); - long delay = 1000 / 25; +// long delay = 1000 / 25; this sounds quite frequent + long delay = 1000 / 10; lastTrigger = System.currentTimeMillis(); - timer.scheduleAtFixedRate(task, delay, delay); + timer.scheduleAtFixedRate(task, delay, delay, TimeUnit.MILLISECONDS); } @HintListener(Class = Hints.class, Field = "KEY_CANVAS_BOUNDS")