I want to close a dialog after a specified timeout. So far I have the following method:
public static void addTimeout(final Component c, long timeout) {
Timer t = new Timer(c.getName() + "-TimeoutTimer");
t.schedule(new TimerTask() {
#Override
public void run() {
if (c.isVisible()) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
c.setVisible(false);
}
});
}
}
}, timeout);
}
However, I would like to know if there is a more compact way to write it. For example, avoiding to set a timer and just calling a method to run code on EDT with a specified delay. Is that possible?
Not really. If you switch to using the (more modern) java.util.concurrent way of doing things, you can use two lambdas and do it like this:
public static void addTimeout(final Component c, long timeout) {
Executors.newSingleThreadScheduledExecutor().schedule(() -> {
if (c.isVisible()) {
SwingUtilities.invokeLater(() -> {
c.setVisible(false);
});
}
return null;
}, timeout, TimeUnit.MILLISECONDS);
}
...which is more compact. But aside from switching to a scheduled thread executor, it's really just syntactic sugar on what you have above.
(Side note: If actually using the above code, it'd probably be better to store the result of Executors.newSingleThreadScheduledExecutor() for future invocations.)
Related
I have a thread in Java that makes a web call and stores the information retrieved, but it only retrieves information for that particular instant. I'd like to run this thread every second for a certain period of time to get a better view of the data. How can I do this? I've looked at ScheduledExecutorService, and from what I can tell if the thread is still running when it's time to set up the next run, it waits until the first thread is complete, which isn't what I'm looking for.
You can do this by a double schedule. Use scheduleWithFixedDelay() to set off a job every second. This job starts the method which you really want to run. Here is some code based on Oracle's ScheduledExecutorService API.
The Thread.sleep() is there to simulate a long-running task.
class Beeper {
public static void main(String[] args) {
(new Beeper()).beep();
}
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public void beep() {
final Runnable beeper = new Runnable() {
public void run() {
System.out.println("beep");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
final Runnable beeper2 = new Runnable() {
public void run() {
(new Thread(beeper)).start();
}
};
final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(beeper2, 1, 1, SECONDS);
}
}
What you need is the scheduleAtFixedRate method: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html#scheduleAtFixedRate(java.lang.Runnable,%20long,%20long,%20java.util.concurrent.TimeUnit)
When the scheduler waits until the first thread is complete, it's because you're using scheduleWithFixedDelay.
However, if you absolutely want the threads run concurrently, you should try this:
pool.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
pool.submit(myJob);
}
}, 1, 1, TimeUnit.SECONDS);
I advise to always use a pool.
What about this?
public static void main (String [] args) throws InterruptedException{
ExecutorService executorService =
Executors.newFixedThreadPool(10);
while (true){
executorService.submit(new Runnable() {
#Override
public void run() {
// do your work here..
System.out.println("Executed!");
}});
Thread.sleep(1000);
}
}
I am doing some frequent operations, which require GUI refresh (adding some children to a control).
I can't control the moment when the entire bunch of additions finished, so I can't do update/redraw/layout/refresh at the end and need do it each step.
Simultaneously I need nod do it very frequent, because user need not see each change.
Also each update/redraw/layout/refresh slows the process.
So, I need to decide whether to update/redraw/layout/refresh by time.
I wrote the following general class for SWT, but similar also applicable to Swing.
Is it's logic complete and correct? Especially, will the check delayedMap.get(doRun) == timer work correctly in multithreading? It's purpose is to cancel delayed operation in the case if entering the invokeOnceDelayed() method is occured between enterings into TimerTask.run() and inner synchronized block?
public class SWTUtilities {
private static HashMap<Runnable, Timer> delayedMap = new HashMap<Runnable, Timer>();
public static void invokeLater(Runnable doRun) {
Display.getDefault().asyncExec(doRun);
}
public static void invokeAndWait(Runnable doRun) {
Display.getDefault().syncExec(doRun);
}
public static synchronized void invokeOnceDelayed(final Runnable doRun, long delay) {
final Timer timer = new Timer(true);
Timer oldTimer = delayedMap.put(doRun, timer);
if( oldTimer != null ) {
oldTimer.cancel();
}
timer.schedule(new TimerTask() {
#Override
public void run() {
synchronized(SWTUtilities.class) {
if( delayedMap.get(doRun) == timer ) {
invokeLater(doRun);
}
}
}}, delay);
}
}
You can probably just delegate to Display.timerExec for the implementation of invokeOnceDelayed() method.
Is there a lightweight pattern to cancel long running method, which replaces code like this:
public void longComputations() {
... first step...
if ( cancelled ) {
rollbackWork();
return;
}
... second step...
if ( cancelled ) {
rollbackWork();
return;
}
... third step...
if ( cancelled ) {
rollbackWork();
return;
}
}
I know that I can make a Task class, subdivide steps to task objects, make a queue and just do tasks step by steps in loop with cancelation checking, but I'm just wondering is there any simple code-structure pattern for such situation.
I am not aware of such a mechanism. Since you have to track your work in order to be able to perform rollbackWork(), a well-designed object-oriented solution is your best choice anyway, if you want to further evolve this logic! Typically, such a scenario could be implemented using the command pattern, which I still find pretty lightweight:
// Task or Command
public interface Command {
void redo();
void undo();
}
A scheduler or queue could then take care of executing such task / command implementations, and of rolling them back in order.
How about this edit, not a pattern though? Exceptions are very cheap, so it should be fast.
public void caller(){
try{
longComputations();
} catch (MeaningfulRuntimeException e){
rollbackWork(e.getStep());
}
}
public void longComputations() {
... first step...
checkStatus(1);
... second step...
checkStatus(2);
... third step...
checkStatus(3);
}
public void checkStatus(int step){
if ( cancelled ) {
... we may rollback here or throw an exception ...
throw MeaningfulRuntimeException(step);
}
}
If the steps call methods which throw InterruptedException then you can use Thread.interrupt(). You will still need to maintain enough state information to do the rollback properly.
If the steps cannot be interrupted this way, you should not consider relying on the deprecated Thread.stop() mechanism since it is inherently unsafe.
It seems that either way it makes sense to do exactly what you described: encapsulate this workflow logic in a class independent of the computation steps. It should support cancellation and/or interruption and accept a bunch of tasks to be executed. Note that the tasks to be fed into the workflow should provide at least two methods: one to perform the computation and one to roll it back.
You might want to consider using the java.util.concurrent package. You need to wrap your working steps as Callables (or Runnables).
public class InterruptibleTest {
public static void main(String[] args) { try {
final ExecutorService queue = Executors.newFixedThreadPool(1);
queue.submit(new Callable<Void>() { #Override public Void call() { busyWait(1000); return null; } });
queue.submit(new Callable<Void>() { #Override public Void call() { busyWait(1000); return null; } });
queue.submit(new Callable<Void>() { #Override public Void call() { busyWait(1000); return null; } });
final AtomicBoolean cancelled = new AtomicBoolean();
new Thread() { #Override public void run() {
try { Thread.sleep(1500); } catch (InterruptedException ex) { }
queue.shutdownNow();
cancelled.set(true);
}
}.run();
if (cancelled.get()) { rollback(); }
queue.shutdown();
System.out.println("Finished");
} catch (Exception ex) { ex.printStackTrace(System.err); } }
public synchronized static void busyWait(int millis) {
System.out.println("Start");
long until = System.currentTimeMillis() + millis;
while (System.currentTimeMillis() < until) { }
System.out.println("Stopped");
}
public synchronized static void rollback() {
System.out.println("Rollback!");
}
}
Note that shutdownNow() might call interrupt() on the currently executing work thread. You will probably also need to synchronize your rollback() because shutdownNow() returns before non-interruptible code finishes execution.
I want a method that runs 2 or more methods in separate threads. I want be sure that method won't finish before all threads are done.
The best approach is to utilize the Executor Service API to manage a thread pool instead of starting an open-ended number of threads on your own.
ExecutorService pool = Executors.newCachedThreadPool();
for (Runnable r : new Runnable[] {
new R() { void r() { myMethod1(); }},
new R() { void r() { myMethod2(); }},
})
pool.execute(r);
pool.shutdown();
pool.awaitTermination(60, TimeUnit.SECONDS);
abstract class R implements Runnable
public final void run() { r(); }
abstract void r();
}
Note that it is not advisable to insist on every method running in its own, separate thread. Threads are quite heavyweight (each allocating a complete call stack) and performance actually decreases as the thread count increases far beyond the number of available processor cores.
I prefer something like this:
public static void runParallel(Runnable... runnables) throws InterruptedException {
final CountDownLatch done = new CountDownLatch(runnables.length);
for (final Runnable r: runnables) {
new Thread(new Runnable() {
public void run() {
try {
r.run();
} finally {
done.countDown();
}
}
}).start();
}
done.await();
}
An advantage of this approach is that it also works with thread pool (i.e. you can replace new Thread(...).start() with executor.submit(...)).
Also it allows you to use pre-existing thread pool, unlike solutions based on awaitTermination() that force you to create new pools for each invocation.
My solution is
Function:
public void runParallel(Runnable... runnables) throws InterruptedException {
List<Thread> threads = new ArrayList<Thread>(runnables.length);
for (Runnable runnable :runnables) {
Thread th = new Thread(runnable);
threads.add(th);
th.start();
}
for (Thread th : threads) {
th.join();
}
Use:
runParallel(new Runnable() {
#Override
public void run() {
method1()
}
}, new Runnable() {
#Override
public void run() {
method2()
}
}
);
any better ideas? Maybe there is a shorter way that I'm not aware of ;)
Following the API given by damienix:
public void runParallel(Runnable... runnables) throws InterruptedException {
final ExecutorService pool = Executors.newFixedThreadPool(runnables.length);
for (Runnable runnable: runnables) {
pool.submit(runnable);
}
pool.shutdown();
pool.awaitTermination(1, TimeUnit.MINUTES);
}
What the best practice to run thread only for some period?
I can easily check curentTime and close the thread after in worked for some time, but I think it's not the right way.
It depends on what you want to achieve, but generally speaking the approach you mentioned with measuring the time from the start is not that wrong.
I would code it like this:
private static class MyTimerTask extends TimerTask {
private final Thread target;
public MyTimerTask(Thread target) { this.target = target; }
public void run() {
target.interrupt();
}
}
public void run() {
Thread final theThread = Thread.currentThread();
Timer timer = new Timer();
try {
timer.schedule(new MyTimerTask(theThread), 60000});
while(!theThread.interrupted()) {
....
}
} finally {
timer.cancel();
}
}
... which is Hovercraft described, except using interrupt instead of an ad-hoc flag. Using interrupts has the advantage that some I/O calls are unblocked by an interrupt, and some libraries will respect it.
I'm surprised (and deeply disappointed) that no one has mentioned the Executors framework. It has usurped the Timer framework (or at least the java.util.Timer class) as the "goto" for scheduled tasks.
For instance,
// Start thread
final Thread t = new Thread(new Runnable(){
#Override
public void run(){
while(!Thread.currentThread().isInterrupted()){
try{
// do stuff
}
catch(InterruptedException e){
Thread.currentThread().interrupt();
}
}
}
});
t.start();
// Schedule task to terminate thread in 1 minute
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.schedule(new Runnable(){
#Override
public void run(){
t.interrupt();
}
}, 1, TimeUnit.MINUTES);