Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Implements Executor delayed and fixed rate periodic tasks #184

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip
Binary file not shown.
2 changes: 1 addition & 1 deletion sources/net.sf.j2s.core/dist/swingjs/timestamp
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20201203153534
20201203173354
Binary file modified sources/net.sf.j2s.core/dist/swingjs/ver/3.2.9/SwingJS-site.zip
Binary file not shown.
2 changes: 1 addition & 1 deletion sources/net.sf.j2s.core/dist/swingjs/ver/3.2.9/timestamp
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20201203153534
20201203173354
Binary file modified sources/net.sf.j2s.java.core/dist/SwingJS-site.zip
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,14 @@ private class ScheduledFutureTask<V>
/** 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<V> outerTask = this;
Expand Down Expand Up @@ -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 */
Expand All @@ -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();
}
}

Expand All @@ -348,25 +347,23 @@ void reExecutePeriodic(RunnableScheduledFuture<?> task) {
* due to shutdown policy. Invoked within super.shutdown.
*/
@Override void onShutdown() {
BlockingQueue<Runnable> q = super.getQueue();
// BlockingQueue<Runnable> 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<Integer, RunnableScheduledFuture<?>> 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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@ private void decrementWorkerCount() {
* bounded by CAPACITY.
*/
private volatile int maximumPoolSize;
private boolean stopped;

/**
* The default rejected execution handler
Expand Down Expand Up @@ -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
// }
}

/*
Expand Down Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -1437,7 +1441,7 @@ public List<Runnable> shutdownNow() {
}

public boolean isShutdown() {
return ! isRunning(ctl.get());
return stopped;//! isRunning(ctl.get());
}

/**
Expand Down
75 changes: 62 additions & 13 deletions sources/net.sf.j2s.java.core/src/test/Test_Future.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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);

Expand Down