ScheduledFuture and Binary latch

View: New views
6 Messages — Rating Filter:   Alert me  

ScheduledFuture and Binary latch

by iksrazal :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi all, allow this code to explain:

public class ParseTask implements Runnable {

   private static final Logger _log = Logger.getLogger();
   private static final ThreadFactory factory = new
ONExceptionThreadFactory(new ONExceptionHandler());
   private static final ExecutorService executorService =
Executors.newSingleThreadScheduledExecutor(factory);
   private static final BinaryLatch binaryLatch = new BinaryLatch();

       public void run() {
           if (binaryLatch.isRunning()) {
               // skip task if its already running
               return;
           }
           Future future = executorService.submit(new ParseJob());
           try {
               // wait and timeout or return result
               future.get(300, TimeUnit.SECONDS);
           } catch (InterruptedException ex) {
              _log.error(ex.getMessage(), ex);
              // Re-assert the thread's interrupted status
              Thread.currentThread().interrupt();
              // We don't need the result, so cancel the task too
              future.cancel(true);
           } catch (Exception ex) {
              _log.error(ex.getMessage(), ex);
              throw ThreadUtils.launderThrowable(ex.getCause());
          }
       }
}

This ParseTask is started via a Servlet init() as:

ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture <?> scheduledParseJob = ses.scheduleWithFixedDelay(new
ParseTask(),
                 0L, 1, TimeUnit.MINUTES);

Problem: I want to write a latch, perhaps a semaphore, that skips this
task if its already running. So I want to acquire some type of lock
when I start this task, skip the task if its already been started, and
release the lock when this single task is completed. CountDownLatch
doesn't seem right for a repeatable task. I've written a few versions
of BinaryLatch but nothing seems right to me. Any ideas?

Robert
_______________________________________________
Concurrency-interest mailing list
Concurrency-interest@...
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest

Re: ScheduledFuture and Binary latch

by Joe Bowbeer :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Jun 5, 2008 at 3:02 PM, robert lazarski wrote:
>
> Problem: I want to write a latch, perhaps a semaphore, that skips this
> task if its already running. So I want to acquire some type of lock
> when I start this task, skip the task if its already been started, and
> release the lock when this single task is completed. CountDownLatch
> doesn't seem right for a repeatable task. I've written a few versions
> of BinaryLatch but nothing seems right to me. Any ideas?
>

final AtomicBoolean isRunning = new AtomicBoolean()

if (isRunning.compareAndSet(false, true))
    try {
        // run task
    } finally {
        isRunning.set(false);
    }
_______________________________________________
Concurrency-interest mailing list
Concurrency-interest@...
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest

Re: ScheduledFuture and Binary latch

by Jim Newsham-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


I usually use an AtomicBoolean for this type of thing.

private AtomicBoolean running = new AtomicBoolean();

...


public void run() {
  if (running.compareAndSet(false, true)) {
    try {
      // ...do work...
    }
    finally {
      running.set(false);
    }
  }
}

> -----Original Message-----
> From: concurrency-interest-bounces@... [mailto:concurrency-
> interest-bounces@...] On Behalf Of robert lazarski
> Sent: Thursday, June 05, 2008 12:03 PM
> To: concurrency-interest@...
> Subject: [concurrency-interest] ScheduledFuture and Binary latch
>
> Hi all, allow this code to explain:
>
> public class ParseTask implements Runnable {
>
>    private static final Logger _log = Logger.getLogger();
>    private static final ThreadFactory factory = new
> ONExceptionThreadFactory(new ONExceptionHandler());
>    private static final ExecutorService executorService =
> Executors.newSingleThreadScheduledExecutor(factory);
>    private static final BinaryLatch binaryLatch = new BinaryLatch();
>
>        public void run() {
>            if (binaryLatch.isRunning()) {
>                // skip task if its already running
>                return;
>            }
>            Future future = executorService.submit(new ParseJob());
>            try {
>                // wait and timeout or return result
>                future.get(300, TimeUnit.SECONDS);
>            } catch (InterruptedException ex) {
>               _log.error(ex.getMessage(), ex);
>               // Re-assert the thread's interrupted status
>               Thread.currentThread().interrupt();
>               // We don't need the result, so cancel the task too
>               future.cancel(true);
>            } catch (Exception ex) {
>               _log.error(ex.getMessage(), ex);
>               throw ThreadUtils.launderThrowable(ex.getCause());
>           }
>        }
> }
>
> This ParseTask is started via a Servlet init() as:
>
> ScheduledExecutorService ses =
> Executors.newSingleThreadScheduledExecutor();
> ScheduledFuture <?> scheduledParseJob = ses.scheduleWithFixedDelay(new
> ParseTask(),
>                  0L, 1, TimeUnit.MINUTES);
>
> Problem: I want to write a latch, perhaps a semaphore, that skips this
> task if its already running. So I want to acquire some type of lock
> when I start this task, skip the task if its already been started, and
> release the lock when this single task is completed. CountDownLatch
> doesn't seem right for a repeatable task. I've written a few versions
> of BinaryLatch but nothing seems right to me. Any ideas?
>
> Robert
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest@...
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest



_______________________________________________
Concurrency-interest mailing list
Concurrency-interest@...
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest

Parent Message unknown Re: ScheduledFuture and Binary latch

by Ben Manes :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.
I believe that you could use a flag (volatile boolean; AtomicBoolean) or a try-lock approach.

----- Original Message ----
From: robert lazarski <robertlazarski@...>
To: concurrency-interest@...
Sent: Thursday, June 5, 2008 3:02:42 PM
Subject: [concurrency-interest] ScheduledFuture and Binary latch

Hi all, allow this code to explain:

public class ParseTask implements Runnable {

  private static final Logger _log = Logger.getLogger();
  private static final ThreadFactory factory = new
ONExceptionThreadFactory(new ONExceptionHandler());
  private static final ExecutorService executorService =
Executors.newSingleThreadScheduledExecutor(factory);
  private static final BinaryLatch binaryLatch = new BinaryLatch();

      public void run() {
          if (binaryLatch.isRunning()) {
              // skip task if its already running
              return;
          }
          Future future = executorService.submit(new ParseJob());
          try {
              // wait and timeout or return result
              future.get(300, TimeUnit.SECONDS);
          } catch (InterruptedException ex) {
              _log.error(ex.getMessage(), ex);
              // Re-assert the thread's interrupted status
              Thread.currentThread().interrupt();
              // We don't need the result, so cancel the task too
              future.cancel(true);
          } catch (Exception ex) {
              _log.error(ex.getMessage(), ex);
              throw ThreadUtils.launderThrowable(ex.getCause());
          }
      }
}

This ParseTask is started via a Servlet init() as:

ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture <?> scheduledParseJob = ses.scheduleWithFixedDelay(new
ParseTask(),
                0L, 1, TimeUnit.MINUTES);

Problem: I want to write a latch, perhaps a semaphore, that skips this
task if its already running. So I want to acquire some type of lock
when I start this task, skip the task if its already been started, and
release the lock when this single task is completed. CountDownLatch
doesn't seem right for a repeatable task. I've written a few versions
of BinaryLatch but nothing seems right to me. Any ideas?

Robert
_______________________________________________
Concurrency-interest mailing list
Concurrency-interest@...
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
Concurrency-interest@...
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest

Parent Message unknown Re: ScheduledFuture and Binary latch

by Kevin Condon :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

In addition to the recommendations for using AtomicBoolean, I also notice that the use of scheduleWithFixedDelay() should in itself prevent overlapping executions of the task without any checks in the task itselt.  According to the javadoc:  "Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given delay between the termination of one execution and the commencement of the next."  The following test code confirms:

public class Tst {
  public static void main(String[] args) {
    ScheduledExecutorService exec =
      Executors.newSingleThreadScheduledExecutor();
    exec.scheduleWithFixedDelay(
      new LongRun(), 0L, 1000L, TimeUnit.MILLISECONDS);
  }

  private static class LongRun implements Runnable {
    private final AtomicInteger nextId = new AtomicInteger(0);

    public void run() {
      int id = nextId.getAndIncrement();
      System.out.println(new Date() + " " + id + " starting");
      try {
        Thread.sleep(10000L);
      } catch (InterruptedException ex) {
        // fall through and exit
      } finally {
        System.out.println(new Date() + " " + id + " done");
      }
    }
  }
}

Output indicates the task runs for 10 sec, then after a 1 sec delay it runs again:
Fri Jun 06 10:19:24 EDT 2008 0 starting
Fri Jun 06 10:19:34 EDT 2008 0 done
Fri Jun 06 10:19:35 EDT 2008 1 starting
Fri Jun 06 10:19:45 EDT 2008 1 done
Fri Jun 06 10:19:46 EDT 2008 2 starting
Fri Jun 06 10:19:56 EDT 2008 2 done

Regards,
Kevin

From: "robert lazarski" <robertlazarski@...>
To: concurrency-interest@...
Date: Thu, 5 Jun 2008 19:02:42 -0300
Subject: [concurrency-interest] ScheduledFuture and Binary latch
Hi all, allow this code to explain:

public class ParseTask implements Runnable {

  private static final Logger _log = Logger.getLogger();
  private static final ThreadFactory factory = new
ONExceptionThreadFactory(new ONExceptionHandler());
  private static final ExecutorService executorService =
Executors.newSingleThreadScheduledExecutor(factory);
  private static final BinaryLatch binaryLatch = new BinaryLatch();

      public void run() {
          if (binaryLatch.isRunning()) {
              // skip task if its already running
              return;
          }
          Future future = executorService.submit(new ParseJob());
          try {
              // wait and timeout or return result
              future.get(300, TimeUnit.SECONDS);
          } catch (InterruptedException ex) {
             _log.error(ex.getMessage(), ex);
             // Re-assert the thread's interrupted status
             Thread.currentThread().interrupt();
             // We don't need the result, so cancel the task too
             future.cancel(true);
          } catch (Exception ex) {
             _log.error(ex.getMessage(), ex);
             throw ThreadUtils.launderThrowable(ex.getCause());
         }
      }
}

This ParseTask is started via a Servlet init() as:

ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture <?> scheduledParseJob = ses.scheduleWithFixedDelay(new
ParseTask(),
                0L, 1, TimeUnit.MINUTES);

Problem: I want to write a latch, perhaps a semaphore, that skips this
task if its already running. So I want to acquire some type of lock
when I start this task, skip the task if its already been started, and
release the lock when this single task is completed. CountDownLatch
doesn't seem right for a repeatable task. I've written a few versions
of BinaryLatch but nothing seems right to me. Any ideas?

Robert

_______________________________________________
Concurrency-interest mailing list
Concurrency-interest@...
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest

Parent Message unknown Re: ScheduledFuture and Binary latch

by Kevin Condon :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Doh.  Now I see why you need the active task check.  Somehow missed the submit in the ParseTask.run() ...

Regards,
Kevin
 
From: "Kevin Condon" <conivek@...>
To: concurrency-interest@...
Date: Fri, 6 Jun 2008 10:24:05 -0400
Subject: Re: [concurrency-interest] ScheduledFuture and Binary latch
Hi,

In addition to the recommendations for using AtomicBoolean, I also notice that the use of scheduleWithFixedDelay() should in itself prevent overlapping executions of the task without any checks in the task itselt.  According to the javadoc:  "Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given delay between the termination of one execution and the commencement of the next."  The following test code confirms:

public class Tst {
  public static void main(String[] args) {
    ScheduledExecutorService exec =
      Executors.newSingleThreadScheduledExecutor();
    exec.scheduleWithFixedDelay(
      new LongRun(), 0L, 1000L, TimeUnit.MILLISECONDS);
  }

  private static class LongRun implements Runnable {
    private final AtomicInteger nextId = new AtomicInteger(0);

    public void run() {
      int id = nextId.getAndIncrement();
      System.out.println(new Date() + " " + id + " starting");
      try {
        Thread.sleep(10000L);
      } catch (InterruptedException ex) {
        // fall through and exit
      } finally {
        System.out.println(new Date() + " " + id + " done");
      }
    }
  }
}

Output indicates the task runs for 10 sec, then after a 1 sec delay it runs again:
Fri Jun 06 10:19:24 EDT 2008 0 starting
Fri Jun 06 10:19:34 EDT 2008 0 done
Fri Jun 06 10:19:35 EDT 2008 1 starting
Fri Jun 06 10:19:45 EDT 2008 1 done
Fri Jun 06 10:19:46 EDT 2008 2 starting
Fri Jun 06 10:19:56 EDT 2008 2 done

Regards,
Kevin

_______________________________________________
Concurrency-interest mailing list
Concurrency-interest@...
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
LightInTheBox - Buy quality products at wholesale price