diff --git a/sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip b/sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip index cee084b33..130d17bf9 100644 Binary files a/sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip and b/sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip differ diff --git a/sources/net.sf.j2s.core/dist/swingjs/timestamp b/sources/net.sf.j2s.core/dist/swingjs/timestamp index 36243d310..e3a9fe0d3 100644 --- a/sources/net.sf.j2s.core/dist/swingjs/timestamp +++ b/sources/net.sf.j2s.core/dist/swingjs/timestamp @@ -1 +1 @@ -20201203153534 +20201203173354 diff --git a/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.9/SwingJS-site.zip b/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.9/SwingJS-site.zip index cee084b33..130d17bf9 100644 Binary files a/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.9/SwingJS-site.zip and b/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.9/SwingJS-site.zip differ diff --git a/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.9/timestamp b/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.9/timestamp index 36243d310..e3a9fe0d3 100644 --- a/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.9/timestamp +++ b/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.9/timestamp @@ -1 +1 @@ -20201203153534 +20201203173354 diff --git a/sources/net.sf.j2s.java.core/dist/SwingJS-site.zip b/sources/net.sf.j2s.java.core/dist/SwingJS-site.zip index cee084b33..130d17bf9 100644 Binary files a/sources/net.sf.j2s.java.core/dist/SwingJS-site.zip and b/sources/net.sf.j2s.java.core/dist/SwingJS-site.zip differ diff --git a/sources/net.sf.j2s.java.core/src/java/util/concurrent/ScheduledThreadPoolExecutor.java b/sources/net.sf.j2s.java.core/src/java/util/concurrent/ScheduledThreadPoolExecutor.java index e2dd6dcb1..e669222ca 100644 --- a/sources/net.sf.j2s.java.core/src/java/util/concurrent/ScheduledThreadPoolExecutor.java +++ b/sources/net.sf.j2s.java.core/src/java/util/concurrent/ScheduledThreadPoolExecutor.java @@ -172,14 +172,14 @@ private class ScheduledFutureTask /** Sequence number to break ties FIFO */ private final long sequenceNumber; /** The time the task is enabled to execute in MilliTime units */ - private long timems; + long timems; /** * Period in milliseconds for repeating tasks. A positive * value indicates fixed-rate execution. A negative value * indicates fixed-delay execution. A value of 0 indicates a * non-repeating task. */ - private final long periodms; + final long periodms; /** The actual task to be re-enqueued by reExecutePeriodic */ RunnableScheduledFuture outerTask = this; @@ -303,17 +303,15 @@ private void delayedExecute(RunnableScheduledFuture task) { if (isShutdown()) reject(task); else { - if (task.isPeriodic()) { - swingjs.JSUtil.notImplemented("Periodic tasks"); - } - if (/** @j2sNative true || */ false) { int[] id = new int[1]; todo.put(id[0] = JSToolkit.dispatch(new Thread(() -> { - RunnableScheduledFuture me = todo.remove(id[0]); - if (me != null) + RunnableScheduledFuture t = todo.remove(id[0]); + if (t != null) { task.run(); + } + }), Math.max(-1, (int) task.getDelay(TimeUnit.MILLISECONDS)), 0), task); } else /** @j2sIgnore */ @@ -335,11 +333,12 @@ private void delayedExecute(RunnableScheduledFuture task) { */ void reExecutePeriodic(RunnableScheduledFuture task) { if (canRunInCurrentRunState(true)) { - super.getQueue().add(task); - if (!canRunInCurrentRunState(true) && remove(task)) - task.cancel(false); - else - prestartCoreThread(); + delayedExecute(task); +// super.getQueue().add(task); +// if (!canRunInCurrentRunState(true) && remove(task)) +// task.cancel(false); +// else +// prestartCoreThread(); } } @@ -348,25 +347,23 @@ void reExecutePeriodic(RunnableScheduledFuture task) { * due to shutdown policy. Invoked within super.shutdown. */ @Override void onShutdown() { - BlockingQueue q = super.getQueue(); + // BlockingQueue q = super.getQueue(); boolean keepDelayed = getExecuteExistingDelayedTasksAfterShutdownPolicy(); boolean keepPeriodic = getContinueExistingPeriodicTasksAfterShutdownPolicy(); - if (!keepDelayed && !keepPeriodic) - q.clear(); - else { + if (!keepDelayed && !keepPeriodic) { + todo.clear(); +// q.clear(); + } else { // Traverse snapshot to avoid iterator exceptions - for (Object e : q.toArray()) { - if (e instanceof RunnableScheduledFuture) { - RunnableScheduledFuture t = - (RunnableScheduledFuture)e; + for (Map.Entry> e: todo.entrySet()) { + RunnableScheduledFuture t = e.getValue(); if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed) || t.isCancelled()) { // also remove if already cancelled - if (q.remove(t)) + todo.remove(t); t.cancel(false); } - } } } tryTerminate(); diff --git a/sources/net.sf.j2s.java.core/src/java/util/concurrent/ThreadPoolExecutor.java b/sources/net.sf.j2s.java.core/src/java/util/concurrent/ThreadPoolExecutor.java index 40dc95cfa..7153b2af6 100644 --- a/sources/net.sf.j2s.java.core/src/java/util/concurrent/ThreadPoolExecutor.java +++ b/sources/net.sf.j2s.java.core/src/java/util/concurrent/ThreadPoolExecutor.java @@ -541,6 +541,7 @@ private void decrementWorkerCount() { * bounded by CAPACITY. */ private volatile int maximumPoolSize; + private boolean stopped; /** * The default rejected execution handler @@ -689,34 +690,35 @@ private void advanceRunState(int targetState) { * allow access from ScheduledThreadPoolExecutor. */ final void tryTerminate() { - for (;;) { - int c = ctl.get(); - if (isRunning(c) || - runStateAtLeast(c, TIDYING) || - (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty())) - return; - if (workerCountOf(c) != 0) { // Eligible to terminate - interruptIdleWorkers(ONLY_ONE); - return; - } - - final ReentrantLock mainLock = this.mainLock; - mainLock.lock(); - try { - if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) { - try { - terminated(); - } finally { - ctl.set(ctlOf(TERMINATED, 0)); - termination.signalAll(); - } - return; - } - } finally { - mainLock.unlock(); - } - // else retry on failed CAS - } + terminated(); +// for (;;) { +// int c = ctl.get(); +// if (isRunning(c) || +// runStateAtLeast(c, TIDYING) || +// (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty())) +// return; +// if (workerCountOf(c) != 0) { // Eligible to terminate +// interruptIdleWorkers(ONLY_ONE); +// return; +// } +// +// final ReentrantLock mainLock = this.mainLock; +// mainLock.lock(); +// try { +// if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) { +// try { +// terminated(); +// } finally { +// ctl.set(ctlOf(TERMINATED, 0)); +// termination.signalAll(); +// } +// return; +// } +// } finally { +// mainLock.unlock(); +// } +// // else retry on failed CAS +// } } /* @@ -841,8 +843,9 @@ void onShutdown() { * @param shutdownOK true if should return true if SHUTDOWN */ final boolean isRunningOrShutdown(boolean shutdownOK) { - int rs = runStateOf(ctl.get()); - return rs == RUNNING || (rs == SHUTDOWN && shutdownOK); + return (shutdownOK || !stopped); +// int rs = runStateOf(ctl.get()); +// return rs == RUNNING || (rs == SHUTDOWN && shutdownOK); } /** @@ -1394,16 +1397,17 @@ else if (!addWorker(command, false)) * @throws SecurityException {@inheritDoc} */ public void shutdown() { - final ReentrantLock mainLock = this.mainLock; - mainLock.lock(); - try { - checkShutdownAccess(); - advanceRunState(SHUTDOWN); +// final ReentrantLock mainLock = this.mainLock; +// mainLock.lock(); +// try { +// checkShutdownAccess(); +// advanceRunState(SHUTDOWN); + stopped = true; interruptIdleWorkers(); onShutdown(); // hook for ScheduledThreadPoolExecutor - } finally { - mainLock.unlock(); - } +// } finally { +// mainLock.unlock(); +// } tryTerminate(); } @@ -1437,7 +1441,7 @@ public List shutdownNow() { } public boolean isShutdown() { - return ! isRunning(ctl.get()); + return stopped;//! isRunning(ctl.get()); } /** diff --git a/sources/net.sf.j2s.java.core/src/test/Test_Future.java b/sources/net.sf.j2s.java.core/src/test/Test_Future.java index 73070ccca..af9380362 100644 --- a/sources/net.sf.j2s.java.core/src/test/Test_Future.java +++ b/sources/net.sf.j2s.java.core/src/test/Test_Future.java @@ -19,7 +19,9 @@ import test.baeldung.doublecolon.Computer; import test.baeldung.doublecolon.MacbookPro; +import java.awt.BorderLayout; import java.awt.Color; +import java.awt.Dimension; import java.awt.event.ActionEvent; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; @@ -31,6 +33,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.SwingUtilities; @@ -40,26 +43,72 @@ public class Test_Future extends JFrame { Executor executor = (Runnable r) -> { new Thread(r).start(); }; - private JButton button; - + private JButton b1, b2; + public Test_Future() { - setVisible(true); - setBounds(500, 300, 400, 300); + setLocation(400,200); setDefaultCloseOperation(EXIT_ON_CLOSE); - button = new JButton("PRESS ME"); - button.addActionListener((ActionEvent e) -> { - btnAction(); + b1 = new JButton("fixed"); + b1.setPreferredSize(new Dimension(120,40)); + b1.addActionListener((ActionEvent e) -> { + btnAction(b1,true); }); - add(button); + b1.setName("b1"); + add(b1, BorderLayout.NORTH); + b2 = new JButton("delay"); + b2.setPreferredSize(new Dimension(120,40)); + b2.addActionListener((ActionEvent e) -> { + btnAction(b2,false); + }); + add(b2, BorderLayout.SOUTH); + b2.setName("b2"); + pack(); + setVisible(true); } - Color lastColor = null; + ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor(); - private void btnAction() { - System.out.println("button pressed"); + Color lastColor, lastColor1, lastColor2; + + int nFlash = Integer.MAX_VALUE; + long t0 = 0; - Executors.newSingleThreadScheduledExecutor().schedule(() -> { - button.setForeground(lastColor = (lastColor == Color.red ? Color.blue : Color.red)); + private void btnAction(JButton button, boolean isFixed) { + System.out.println("button pressed"); + if (nFlash < 20 && (button == b1 ? lastColor1 : lastColor2) != null) + return; + nFlash = 0; + t0 = 0; + Runnable r = new Runnable() { + + @Override + public void run() { + if (t0 == 0) + t0 = System.currentTimeMillis(); + System.out.println(button.getName() + " " + nFlash + " " + ((System.currentTimeMillis() - t0) / 1000.)); + if (nFlash++ >= 20) { + System.out.println("done"); + lastColor1 = lastColor2 = null; + exec.shutdown(); + } else { + Color lc = (button == b1 ? lastColor1 : lastColor2); + lc = (lc == Color.green ? Color.blue : Color.green); + button.setForeground(lc); + if (button == b1) + lastColor1 = lc; + else + lastColor2 = lc; + } + } + + }; + if (isFixed) + exec.scheduleAtFixedRate(r, 2000, 500, TimeUnit.MILLISECONDS); + else + exec.scheduleWithFixedDelay(r, 2000, 500, TimeUnit.MILLISECONDS); + + exec.schedule(() -> { + button.setBackground(lastColor = (lastColor == Color.gray ? Color.lightGray : Color.gray)); System.out.println("task complete"); }, 3000, TimeUnit.MILLISECONDS);