Java ScheduledFuture get List - java

This code always returns me 10. I think that problem with receiving list of all features. I need to parse every feature and stop execution scheduler when variable limit will equals 5. How can I do this?
static int limit = 0;
static final int testNum = 10;
static ScheduledExecutorService scheduler;
public static void main(String[] args) {
scheduler = Executors
.newScheduledThreadPool(5);
ScheduledFuture<Integer> future = scheduler.schedule(new ScheduledPrinter(), 10, TimeUnit.SECONDS);
try {
while (true) {
System.out.println(future.get());
if(future.get() != testNum){
return;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
private static class ScheduledPrinter implements Callable<Integer> {
public Integer call() throws Exception {
limit++;
if(limit==5) {
scheduler.shutdown();
return limit;
}
return testNum;
}
}

Let's see What's happening here. scheduler.schedule(new ScheduledPrinter(), 10, TimeUnit.SECONDS) runs the ScheduledPrinter.call() only once. Here is the API docs.
What you want is probably a scheduleAtFixedRate. This takes a Runnable instead of a callable, so the code will look something like this:
static volatile int limit = 0; // make it volatile because of *possible* multithreaded access
// an AtomicInteger would do too
static final int testNum = 10;
static ScheduledExecutorService scheduler;
public static void main(String[] args) {
scheduler = Executors
.newScheduledThreadPool(5);
// discarding the future. No need to use it here.
ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(new ScheduledPrinter(), 10L, 10L, TimeUnit.SECONDS);
}
/** Printing and counting happens here **/
private static class ScheduledPrinter implements Runnable {
#Override
public void run() {
limit++;
if(limit==5) {
scheduler.shutdown();
printNum(limit);
} else {
printNum(testNum);
}
}
private void printNum(int num) {
System.out.println(num);
}
}
Update
OP asked how to return values from Runnable.run() method? Unfortunately, it's impossible. We have to choose between periodical run and a return value because ScheduledExecutorService cannot do both.
It's still possible to get a value out of the Runnable. We must share a reference for this. Here is a rudimentary approach:
final Queue<Integer> numsPrinted = new ConcurrentLinkedQueue<>(); // a concurrent collection
ScheduledFuture<?> future = scheduler.scheduleWithFixedDelay( // using scheduleWithFixedDelay because probably this is what you want
new ScheduledPrinter(numsPrinted), // passing the reference
10L, 10L, TimeUnit.SECONDS);
try {
future.isDone();
Object obj = future.get(80, TimeUnit.SECONDS); // blocks until 80 secs or until the task is done
System.out.println(obj);
System.out.println(Arrays.toString(numsPrinted.toArray()));
} catch (TimeoutException e) {
System.out.println(Arrays.toString(numsPrinted.toArray()));
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
The ScheduledPrinter now looks like this:
private static class ScheduledPrinter implements Runnable {
private final Queue<Integer> numsPrinted;
public ScheduledPrinter(Queue<Integer> numsPrinted) {
this.numsPrinted = numsPrinted; // storing the reference
}
#Override
public void run() {
limit++;
if(limit==5) {
//scheduler.awaitTermination(timeout, unit)
scheduler.shutdown();
storeAndPrintNum(limit);
} else {
storeAndPrintNum(testNum);
}
}
private void storeAndPrintNum(int num) {
numsPrinted.add(num); // using the reference
System.out.println(num);
}
}

The method ScheduledPrinter.call() is called just one time and in the while loop you always return value that was computed once. Thus limit is never incremented and shutdown is never called. So i think you need to change logic, maybe run more threads.

Related

How to stop working ScheduledExecutorService?

In my project I have a chart which can turn into an animation depending on if we click Start or Stop button. I can make it start, but I don't know how to stop it. Method shutdownNow() gives no result. How can I do this? Here is my code
public class Animation extends JPanel{
// initializations
ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
Animation(String s){
// initialization of chart and adding XYSeries
this.add(chartPanel);
}
public void go() {
scheduler.scheduleAtFixedRate( (new Runnable() {
#Override
public void run() {
double first;
l = dataset.getSeries();
while(true) {
first = (double)l.get(0).getY(0);
for (int k = 0; k < l.get(0).getItemCount(); k++) {
if (k + 1 < l.get(0).getItemCount()) l.get(0).updateByIndex(k, l.get(0).getY(k+1));
else l.get(0).updateByIndex(k, first);
}
}
}
}), 0, 5, MILLISECONDS);
}
public void stop() {
scheduler.shutdownNow();
}
}
As per java docs how shutdownNow() works like below.
There are no guarantees beyond best-effort attempts to stop processing
actively executing tasks. For example, typical implementations will
cancel via {#link Thread#interrupt}, so any a task that fails to
respond to interrupts may never terminate.
So, it will set interrupted flag true, so you need to correctly manage the InterruptedException and / or explicitly check Thread.currentThread().isInterrupted(). You can use below code to stop your current running inputted thread.
while (!Thread.currentThread().isInterrupted()) {
// your code here
}
(!Thread.currentThread().isInterrupted())
may be a solution
but personally i would:
extract runner in method
stop runner by flipping a boolean
call scheduler.shutdownNow(); when needed (on close JPanel?)
example:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
boolean running;
public void setup() {
scheduler.scheduleAtFixedRate(runner(), 0, 5, TimeUnit.MILLISECONDS);
}
private Runnable runner() {
return () -> {
while (running) {
try {
//DO YOUR STUFF HERE
System.err.println("RUNNING");
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}
public void go() {
running = true;
}
public void stop() {
running = false ;
}
public void shutdown() {
scheduler.shutdownNow();
}
public static void main(String[] args) throws InterruptedException {
Demo tasks = new Demo();
tasks.setup();
for (int i = 1; i <= 5; i++) {
System.err.println("GO FOR IT " + i);
tasks.go();
Thread.sleep(2000);
tasks.stop();
Thread.sleep(1000);
}
tasks.shutdown();
}

Threading in Sequence

I am trying to learn how to write a program which performs a given set of tasks in sequence with the help of threads. For example, Writing a program which have 3 different threads print 1111…, 22222…., 333333……, so that the output will be 1,2,3,1,2,3,1,2,3…..? OR for e.g. 2 threads one is printing odd numbers and other even numbers, but the output should be printed in sequence - i.e. one even and then odd.
I would like to learn how to write similar kind of programs in which different threads print different stuff concurrently and the output should be printed in sequence.
What is the basic concept in writing these programs. Can we use ThreadPools/Executors for the purpose ? For e.g. can we use
ExecutorService exectorService = Executors.newFixedThreadPool(3);
Can we use Future, FurtureTask, Callable, execute, submit ...? I know these concepts but I am not able to connect the dots for solving the above scenarios.
Please guide me how to go about writing these kind of programs using multithreading / concurrency.
I have written a program using wait()/notifyAll(). Following is the program. I am not executing the consumer as I am printing the whole sequence at the end. Also I am limiting the capacity of the queue to be 15. So I am basically printing the odd / even range till 15.
public class ProduceEven implements Runnable {
private final List<Integer> taskQueue;
private final int MAX_CAPACITY;
public ProduceEven (List<Integer> sharedQueue, int size) {
this.taskQueue = sharedQueue;
this.MAX_CAPACITY = size;
}
#Override
public void run() {
// TODO Auto-generated method stub
int counter = 0;
while (counter < 15) {
try {
produce(counter++);
} catch (InterruptedException e) {
e.getMessage();
}
}
}
private void produce (int i) throws InterruptedException {
synchronized (taskQueue) {
while (taskQueue.size() == MAX_CAPACITY) {
System.out.println("Queue is full : "+Thread.currentThread().getName()+" is waiting , size: "+ taskQueue.size());
taskQueue.wait();
}
Thread.sleep(1000);
if(i%2==0) {
taskQueue.add(i);
}
taskQueue.notifyAll();
}
}
}
public class ProduceOdd implements Runnable {
private final List<Integer> taskQueue;
private final int MAX_CAPACITY;
public ProduceOdd (List<Integer> sharedQueue, int size) {
this.taskQueue = sharedQueue;
this.MAX_CAPACITY = size;
}
#Override
public void run() {
int counter = 0;
while (counter < 15) {
try {
produce(counter++);
} catch (InterruptedException e) {
e.getMessage();
}
}
}
private void produce (int i) throws InterruptedException {
synchronized (taskQueue) {
while (taskQueue.size() == MAX_CAPACITY) {
System.out.println("Queue is full : "+Thread.currentThread().getName()+" is waiting , size: "+ taskQueue.size());
taskQueue.wait();
}
Thread.sleep(1000);
if(i%2==1) {
taskQueue.add(i);
}
taskQueue.notify();
}
}
}
public class OddEvenExampleWithWaitAndNotify {
public static void main(String[] args) {
List<Integer> taskQueue = new ArrayList<Integer>();
int MAX_CAPACITY = 15;
Thread tProducerEven = new Thread(new ProduceEven(taskQueue, MAX_CAPACITY), "Producer Even");
Thread tProducerOdd = new Thread(new ProduceOdd(taskQueue, MAX_CAPACITY), "Producer Odd");
tProducerEven.start();
tProducerOdd.start();
try {
tProducerEven.join();
tProducerOdd.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
ListIterator listIterator = taskQueue.listIterator();
System.out.println("Elements Are:: ");
while(listIterator.hasNext()) {
System.out.print(listIterator.next()+" ");
}
}
}
The output which I get is: Elements Are:: 02134657911810131214
The output is all jumbled up. Why is it not in sequence. 01234567891011121314 What am I missing. I would be now trying to make the program using Semaphores. Also how do we make this program using explicit locks?
Yes, you can use ExecutorService as a starting point to run your threads. You can also create and start your Threads manually, that would make no difference.
The important thing is that your Threads will run in parallel if you do not synchronize them (i.e., they have to wait for one another). To synchronize you can, e.g. use Semaphores or other thread communication mechanisms.
You wrote in the comments you have written a producer/consumer program. It's a bit of the same thing. Each time the 1-Thread produces a 1, the 2-Thread must know that it can now produce a 2. When it is finished, it must let the 3-Thread know that it must produce a 3. The basic concepts are the same. Just the threads have both producer and consumer roles.
Hi this is one sample program to print Odd and Even using two thread and using thread synchronization among them.
Also we have used Executor framework which is not mandatory, you can create thread using new Thread() as well. For quick prototype I have used system.exit() which can be replaced with graceful shutdown of threads like, interruption and all.
package com.ones.twos.threes;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class OnesTwos {
public static void main(String[] args) {
BlockingQueue<Integer> bq1 = new ArrayBlockingQueue<Integer>(100);
BlockingQueue<Integer> bq2 = new ArrayBlockingQueue<Integer>(100);
ExecutorService executorService = Executors.newFixedThreadPool(2);
try {
bq1.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
executorService.submit(new OddEven(bq1, bq2));
executorService.submit(new OddEven(bq2, bq1));
executorService.shutdown();
}
public static class OddEven implements Runnable {
BlockingQueue<Integer> bq1;
BlockingQueue<Integer> bq2;
public OddEven(BlockingQueue<Integer> bq1, BlockingQueue<Integer> bq2) {
this.bq1 = bq1;
this.bq2 = bq2;
}
#Override
public void run() {
while (true) {
try {
int take = bq1.take();
System.out.println(take);
bq2.offer(take + 1);
if (take > 20)
System.exit(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Mycode is also similar to Anirban's, except I am not using executor framework,
public class TestThread {
public static void main(String[] args) {
Boolean bol = new Boolean(true);
(new Thread(new Odd(bol), "odd")).start();
(new Thread(new Even(bol), "even")).start();
}
}
public class Even implements Runnable {
private Boolean flag;
public Even(Boolean b) {
this.flag = b;
}
#Override
public void run() {
for (int i = 2; i < 20; i = i + 2) {
synchronized (flag) {
try {
System.out.println(Thread.currentThread().getName()+":"+i);
Thread.sleep(1000);
flag.notify();
flag.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class Odd implements Runnable {
private Boolean flag;
public Odd(Boolean b) {
this.flag = b;
}
#Override
public void run() {
for (int i = 1; i < 20; i = i + 2) {
synchronized (flag) {
try {
System.out.println(Thread.currentThread().getName()+":"+i);
Thread.sleep(1000);
flag.notify();
flag.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
By establishing the thread pool of 3 (ExecutorService exectorService = Executors.newFixedThreadPool(3); you are essentilly limiting the executor capacity to 3 and other incoming threads will be on hold. If you want to run them in paralel you can just submit them at once. If you want to wait for each other and want to find out the result I suggest you use Callable. Personally I really like Callable because after submiting it you can just call the get method of Future, wait for a returned value from the executed thread and then continue to the next one. From the API you can see this:
/**
* Submits a value-returning task for execution and returns a
* Future representing the pending results of the task. The
* Future's {#code get} method will return the task's result upon
* successful completion.
*
*
* If you would like to immediately block waiting
* for a task, you can use constructions of the form
* {#code result = exec.submit(aCallable).get();}
And a very good example here. If you go for the Callable alternative then you don't need a Thread pool. Just a normal executor is fine. Remember to shut the executor down in the end.
class MyNumber {
int i = 1;
}
class Task implements Runnable {
MyNumber myNumber;
int id;
Task(int id, MyNumber myNumber) {
this.id = id;
this.myNumber = myNumber;
}
#Override
public void run() {
while (true) {
synchronized (myNumber) {
while (myNumber.i != id) {
try {
myNumber.wait(); //Wait until Thread with correct next number
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(id);
if (myNumber.i == 1) {
myNumber.i = 2;
} else if (myNumber.i == 2) {
myNumber.i = 3;
} else {
myNumber.i = 1;
}
myNumber.notifyAll();
}
}
}
}
In main method:
MyNumber myNumber = new MyNumber();
new Thread(new Task(1, myNumber)).start();
new Thread(new Task(2, myNumber)).start();
new Thread(new Task(3, myNumber)).start();
Hi here we have used 2 thread one to print even and another to print odd.
Both are separate and have no relation to each other.
But we have to do a synchronization mechanism between them. Also we need a mechanism to let the ball rolling, i.e. start one thread printing.
Each thread is waiting on condition and after doing it's task it lets other thread work and put ownself in waiting state.
Well happy path works fine, but we need special care when even thread is not in waiting state and the signal() from main fires, in that case even thread will never able to wake up and the program hangs.
So to make sure main thread successfully sends a signal() to even thread and even thread does not miss that we have used Phaser(with party) and checking even thread state in while loop in main.
Code is as below.
package com.ones.twos.threes;
import java.util.concurrent.Phaser;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class OnesTwosTrial2 {
public static void main(String[] args) {
Lock lk = new ReentrantLock();
Phaser ph = new Phaser(3); // to let main start the even thread
Condition even = lk.newCondition();
Condition odd = lk.newCondition();
OnesTwosTrial2 onestwostrial2 = new OnesTwosTrial2();
Thread ev = onestwostrial2.new Evens(lk, even, odd, ph);
Thread od = onestwostrial2.new Odds(lk, even, odd, ph);
ev.start();
od.start();
System.out.println("in main before arrive");
ph.arriveAndAwaitAdvance();
System.out.println("in main after arrive");
// we have to make sure odd and even thread is
// started and waiting on respective condition.
// So we used Phaser with 3, because we are having here
// 3 parties (threads)
// main, odd,even. We will signal only when all the
// threads have started.
// and waiting on conditions.
while (!Thread.State.WAITING.equals(ev.getState())) {
System.out.println("waiting");
}
lk.lock();
even.signal();
lk.unlock();
}
class Evens extends Thread {
Lock lk;
Condition even;
Condition odd;
Phaser ph;
public Evens(Lock lk, Condition even, Condition odd, Phaser ph) {
this.lk = lk;
this.even = even;
this.odd = odd;
this.ph = ph;
}
#Override
public void run() {
System.out.println("even ph");
int cnt = 0;
while (cnt < 20) {
try {
lk.lock();
ph.arrive();
even.await();
System.out.println(cnt);
cnt += 2;
odd.signal();
lk.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Odds extends Thread {
Lock lk;
Condition even;
Condition odd;
Phaser ph;
public Odds(Lock lk, Condition even, Condition odd, Phaser ph) {
this.lk = lk;
this.even = even;
this.odd = odd;
this.ph = ph;
}
#Override
public void run() {
System.out.println("odd ph");
int cnt = 1;
while (cnt < 20) {
try {
lk.lock();
ph.arrive();
odd.await();
System.out.println(cnt);
cnt += 2;
even.signal();
lk.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

Synchronized keyword doesn't work

package threadShareResource1;
public class NonSynchro1 {
private int sum = 0;
public static void main(String[] args) {
NonSynchro1 n = new NonSynchro1();
n.task();
System.out.println(n.getSum());
}
public synchronized void sumAddOne(){
sum++;
}
public void task(){
for (int i = 0; i < 100; i++) {
new Thread(new Runnable(){
#Override
public void run() {
sumAddOne();
}
}).start();
/* try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
} */
}
}
public int getSum() {
return sum;
}
}
Without the commented part of code, the program has data corruption, which is not 100 every time I run it. But I thought the synchronized keyword should acquires a lock on the sumAddOne method, which is the critical region of my program, allowing one thread accessing this method every time.
I've try to use ExecutorService as well, but it doesn't give 100 all the runs.
public void task(){
ExecutorService s = Executors.newCachedThreadPool();
for (int i = 0; i < 100; i++) {
s.execute(new Thread(new Runnable(){
#Override
public void run() {
sumAddOne();
}
}));
}
s.shutdown();
while(!s.isTerminated()){}
}
In Task(), you start 100 threads (which is a lot) and each one is to add 1 to sum.
But when Task is done all you know is that 100 threads are in some process of having started. You don't block before calling println(), so how do you know all the threads have completed?
The sleep probably "prevents the corruption" just because it gives the system time to finish launching all the threads.
Beyond that you are using Synchronized correctly. Any place multiple threads may write to the same variable you need it and, in general (simplifying), you don't need it if you are only reading.
Synchronised keyword is used correctly, the problem is that you are not waiting for the threads to finish. Here is a possible solution:
public class NonSynchro1 {
private static final ExecutorService executorService = Executors.newCachedThreadPool();
private int sum = 0;
public static void main(String[] args) {
NonSynchro1 n = new NonSynchro1();
n.task();
System.out.println(n.getSum());
executorService.shutdown();
}
public synchronized void sumAddOne() {
sum++;
}
public void task() {
List<Callable<Object>> callables = new ArrayList<>();
for (int i = 0; i < 100; i++) {
callables.add(() -> {
sumAddOne();
return null;
});
}
List<Future<Object>> futures;
try {
futures = executorService.invokeAll(callables);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
futures.forEach(future -> {
try {
future.get();
} catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
});
}
public int getSum() {
return sum;
}
}
First we create a list of callables - a list of functions that will be executed in parallel.
Then we invoke them on the executor service. newCachedThreadPool I have used here, by default has 0 threads, it will create as many as necessary to execute all passed callables, the threads will be killed after being idle for a minute.
Finally, in the for-each loop we resolve all futures. get() call will block until the function was executed by the executor service. It will also throw exception if it was thrown inside the function (without calling get() you would not see such exception at all).
Also, it is a good idea to shutdown the executor service when you want to terminate the program gracefully. In this case, it is just executorService.shutdown() at the end of main method. If you don't do this, the program will terminate after a minute when idle threads are killed. However, if different executor service, threads might not be killed when idle, in which case the program would never terminate.
Just for completeness sake: Here's a solution showing how the original program can be made to wait for all threads to finish by joining them:
for (Thread t : n.task())
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
which requires task to return the threads it creates. In this case we don't need to complicate things with caching managers or collections: a simple array will do. Here's the complete class:
public class TestSynchro1 {
private int sum = 0;
public synchronized void sumAddOne() {
sum++;
}
public Thread[] task(int n) {
Thread[] threads = new Thread[n];
for (int i = 0; i < n; i++) {
(threads[i] = new Thread(new Runnable() {
#Override
public void run() {
sumAddOne();
}
})).start();
}
return threads;
}
public static void main(String[] args) {
TestSynchro1 n = new TestSynchro1();
for (Thread t : n.task(100))
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(n.sum);
}
}

starting 10 different thread in java at the sametime

I have 10 different threads which I want to start at the same time. And by same time, I mean not by starting them sequentially (although this will be close).
What is the best way to achieve this in java?
To be accurate: You will not be able to start all 10 threads at the exact same time. There will be some difference in the order ms or ns. You can just try to minimize this difference. And even then: If you have less cores than threads the first couple of threads will have done some work before the others even run their first instruction.
There's a nice example of using a CountDownLatch for that in the Javaspecialists newsletter The Law of the Corrupt Politician.
public class TestCorruption {
private static final int THREADS = 2;
private static final CountDownLatch latch = new CountDownLatch(THREADS);
private static final BankAccount heinz = new BankAccount(1000);
public static void main(String[] args) {
for (int i = 0; i < THREADS; i++) {
addThread();
}
Timer timer = new Timer(true);
timer.schedule(new TimerTask() {
public void run() {
System.out.println(heinz.getBalance());
}
}, 100, 1000);
}
private static void addThread() {
new Thread() {
{
start();
}
public void run() {
latch.countDown();
try {
latch.await();
} catch (InterruptedException e) {
return;
}
while (true) {
heinz.deposit(100);
heinz.withdraw(100);
}
}
};
}
}
It depends on the number of cores your computer have, those will be the number of started threads on the same time, it is my first comment here so i hope this is correct.
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Practica {
private static final int NUMTHREADS = 10;
public static void main(String[] args) {
CountDownLatch cdl = new CountDownLatch(NUMTHREADS);
ExecutorService executor = Executors.newFixedThreadPool(NUMTHREADS);
for (int i = 0; i < NUMTHREADS; i++) {
executor.submit(new Imp(cdl));
cdl.countDown();
System.out.println("one thread sumbmited "+cdl.getCount());
}
System.out.println("All threads submmited");
executor.shutdown();
}
}
class Imp implements Runnable {
CountDownLatch cdl;
public Imp(CountDownLatch arg) {
this.cdl = arg;
}
#Override
public void run() {
try {
cdl.await();
System.out.printf("STARTED %s at %d millis%n",
Thread.currentThread().getName(),
System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

why ExecutorService is not getting frequently executed

There is a method which i need to update frequently for every some specific time , so i was testing java ExecutorService , but my method is not getting frequently updated , could you please tell me why ?
These are my classes
FutureTask.java
package com;
import java.lang.reflect.Method;
import java.util.concurrent.*;
public class FutureTask {
private static ExecutorService executor = Executors.newCachedThreadPool();
private static FutureTask _instance = new FutureTask();
public static FutureTask getInstance() {
return _instance;
}
private static int timoutsec = 15;
public Object submiteTask(final Object obj, final Method method,
final Object[] params) throws Exception {
return submiteTask(obj, method, params, -1);
}
public Object submiteTask(final Object obj, final Method method,
final Object[] params, int timeoutSeconds) throws Exception {
if (null != obj && method != null) {
Callable<Object> task = new Callable<Object>() {
public Object call() {
try {
method.setAccessible(true);
Object resultObj = method.invoke(obj, params);
return resultObj;
} catch (Exception e) {
}
return null;
}
};
Future<Object> future = executor.submit(task);
try {
Object result = null;
if (timeoutSeconds < 0) {
result = future.get(timoutsec, TimeUnit.SECONDS);
} else {
result = future.get(timeoutSeconds, TimeUnit.SECONDS);
}
return result;
} catch (TimeoutException e) {
} catch (Exception e) {
} finally {
future.cancel(true);
}
}
return null;
}
public static void main(String args[]) {
try {
FutureTask.getInstance().submiteTask(
new TestingFutureTaskUtil(),
TestingFutureTaskUtil.class.getDeclaredMethod(
"updateMethodCalled",
new Class<?>[] { String.class }),
new Object[] { "UBSC!OC1010" }, 1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
TestingFutureTaskUtil.java
package com;
public class TestingFutureTaskUtil {
public void updateMethodCalled(String symbol) {
System.out.println("updateMethodCalled" + symbol);
}
}
Thanks in advance .
You only submit one job, so updateMethodCalled is only called once.
You are using a normal ExecutorService. It doesn't allow to schedule tasks. You need to use a ScheduledExecutorService.
You need to change the following:
private static ScheduledExecutorService executor = Executors.newScheduledThreadPool(poolSize);
and:
Future<Object> future = executor.scheduleAtFixedRate(task, timeoutSeconds, timeoutSeconds, TimeUnit.SECONDS);
Now the task will be executed every "timeoutSeconds" Seconds. Afterwards you can return the ScheduledFuture and can get the updated values from it.
Maybe it is just because of the example but I would create an callable outside and hand that to FutureTask. Than you don't need Reflection. Also the way you doing an asynchronous call is wrong because the calling thread always waits for the computation to finish. Therefore, you don't gain any benefits from the running the method in an other thread. Maybe you need to rethink the whole design of what you are doing.

Categories

Resources