I create a Callable which should make a syncExec call. I delegate the Callable to a subclass of RecursiveTask (ForkJoinPool) which executes the call method of the Callable. The problem is that the code inside the run method is never reached. Do you know why and how to fix that?
public class someClass{
public static void main (String[] args){
Callable<Object> c = new Callable<Object>() {
#Override
public Object call() throws Exception {
PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
#Override
public void run() {
System.out.println("hi");
}
});
return null;
}
});
ATLockTask task = new ATLockTask();
task.setCallable(c);
ForkJoinPool pool = new ForkJoinPool();
pool.invoke(task);
}
}
public class ATLockTask extends RecursiveTask<Object[]>{
Callable callable;
#Override
protected Object[] compute() {
try {
callable.call();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
ForkJoinPool.invoke blocks the current thread until the given task has completed. Display.syncExec waits until the SWT UI thread executes Display.readAndDispatch so it will wait forever because ForkJoinPool.invoke is blocking the UI thread.
Use ForkJoinPool.execute to start the task without blocking and the code works.
Related
I have been wanting for a long time to add schedulers to my API. So I set a class for the purpose. Here it is.
public abstract class SyncScheduler extends Scheduler {
private Thread thread = null;
private boolean repeating = false;
#Override
public synchronized void runTask() {
thread = new Thread(this);
thread.start();
}
#Override
public synchronized void runTaskLater(long delay) {
thread = new Thread(this);
try {
Thread.sleep(delay * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.run();
}
#Override
public synchronized void runRepeatingTask(long period) {
thread = new Thread(this);
repeating = true;
while (!thread.isInterrupted()) {
thread.run();
try {
Thread.sleep(period * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public synchronized void cancel() {
if (thread != null || !repeating) {
throw new SchedulerException("Scheduler is not started or is not a repeating task!");
} else {
thread.interrupt();
repeating = false;
}
}}
Scheduler just implements Runnable.
The problem is that whenever I try to create 2 or more Schedulers, the second one never starts until the first one is finished! For example if I have on Scheduler that runs every X seconds and I have another one the cancels it, the one that cancels the first one never starts! This is the problem.
How could I run two of these schedulers in parallel?
Also these are my two test main classes.
public class Test {
static Scheduler scheduler = new SyncScheduler() {
#Override
public void run() {
System.out.println("It works.");
}
};
public static void main(String[] args) {
scheduler.runRepeatingTask(1);
new SyncScheduler() {
#Override
public void run() {
System.out.println("Stopped.");
scheduler.cancel();
}
}.runTaskLater(2);
}}
And here's the second one.
public class Test {
static Scheduler scheduler = new SyncScheduler() {
#Override
public void run() {
System.out.println("It works.");
new SyncScheduler() {
#Override
public void run() {
System.out.println("Stopped.");
scheduler.cancel();
}
}.runTaskLater(2);
}
};
public static void main(String[] args) {
scheduler.runRepeatingTask(1);
}}
The first one outputs "It works." repeatedly until I force stop the test.
The second one gives me "It works." for once, then It gives me "Stopped." and with it and exception.
You are using the thread object wrongly.
To start a Runnable object (in this case, Thread object) in a different thread, the object must call start() method. You are using run() method, which just calling the method in the same thread without creating a new thread.
Try to change run() in SyncScheduler.runRepeatingTask and SyncScheduler.runTaskLater.
Also, I just noticed in your cancel() method:
if (thread != null || !repeating) {
throw new SchedulerException("Scheduler is not started or is not a repeating task!");
} else {
thread.interrupt();
repeating = false;
}
This would make the method throw exception if thread started. I think it should be if (thread == null || !repeating) {
I am trying to execute two method where two methods will execute one by one after some interval, and I am using ExecuterService. I have implemented some portion of the code but the full functionality I could not achieve till now, here I am posting my code
public class ExampleExecuterService {
private static final int MYTHREADS = 3000;
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(MYTHREADS);
Object methodList[]={
aMethod(),bMethod()
};
for(int i=0;i<methodList.length;i++){
Object myList = methodList[i];
Runnable worker = new MyRunnable(myList);
executor.execute(worker);
}
executor.shutdown();
// Wait until all threads are finish
while (!executor.isTerminated()) {
}
System.out.println("\nFinished all threads");
}
public static class MyRunnable implements Runnable {
private Object myList=null;
MyRunnable(Object myList) {
this.myList = myList;
}
#Override
public void run() {
try{
myList.wait(2000);
}catch(Exception e){
e.printStackTrace();
}
}
}
private static Object bMethod() {
System.out.println("This is inside method a ");
return null;
}
private static Object aMethod() {
System.out.println("This is inside method b ");
return null;
}
}
I want aMethod() and bMethod() that should run 20 seconds after and in the end the executer will stop. How to do that with my code. Somebody please help me.
Object methodList[]={
aMethod(),bMethod()
};
This is not a list of your methods. This is a list of what your methods return (=null).
In Java, methods are not objects. If you want to store methods in a list or array, you have to wrap them inside objects. The usual way of doing this is by using the Runnable interface or something of the kind.
In your case, it could look like this:
Runnable[] methods = new Runnable[]{
new Runnable(){ // Object wrapper for method a
#Override
public void run(){ // method a
System.out.println("This is inside method a");
}
},
new Runnable(){ // Object wrapper for waiting
#Override
public void run(){ // method to wait for 20s
try{ Thread.sleep(20000); }catch(Exception e){}
}
},
new Runnable(){ // Object wrapper for method b
#Override
public void run(){ // method b
System.out.println("This is inside method b");
}
}
};
After that you can submit this array of "methods" to your executor service:
ExecutorService service = Executors.newSingleThreadExecutor();
for(Runnable r : methods)
service.submit(r);
service.shutdown();
However, keep in mind that ExecutorService is primarily meant to execute tasks concurrently (= in parallel), while you want to execute them sequentially.
In you know that you'll always need a sequential, single-thread behaviour, you should drop ExecutorService and simply:
for(Runnable r : methods)
r.run();
EDIT: Full main method
public static void main(String[] args) throws Exception {
Runnable[] methods = new Runnable[]{
new Runnable(){ // Object wrapper for method a
#Override
public void run(){ // method a
System.out.println("This is inside method a");
}
},
new Runnable(){ // Object wrapper for waiting
#Override
public void run(){ // method to wait for 20s
try{ Thread.sleep(20000); }catch(Exception e){}
}
},
new Runnable(){ // Object wrapper for method b
#Override
public void run(){ // method b
System.out.println("This is inside method b");
}
}
};
ExecutorService service = Executors.newSingleThreadExecutor();
for(Runnable r : methods)
service.submit(r);
service.shutdown();
// Wait until all threads are finish
while (!service.isTerminated()) {}
System.out.println("\nFinished all threads");
}
I didn't find a better solution for the waiting 20 seconds in between, but how about this:
ExecutorService service = Executors.newSingleThreadExecutor();
service.submit(task1);
service.submit(() -> {
Thread.sleep(20000);
return null;
});
service.submit(task2);
I'm implementing a layer to wrap a 3rd party communication layer.
The contract I need to implement is:
FutureTask<SomeData> send(Request request);
My layer has an onMessageReceived method, which is called by the 3rd party when a response arrives.
The approach I've taken to implement my layer is as follows:
I have a callable, which waits on a condition with a timeout:
interface MyCallable<T> extends Callable<T> {
void signal();
}
class CallableWithSignal<T> implements MyCallable<T> {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private long waitTime;
public CallableWithSignal(int waitTimeSeconds){
this.waitTime=waitTimeSeconds;
}
#Override
public T call() throws Exception {
lock.lock();
try {
boolean wasSignaled = condition.await(waitTime, TimeUnit.SECONDS);
if(wasSignaled)
return null;
System.out.println("throwing exeption");
throw new Exception("timeout");
} finally {
lock.unlock();
}
}
#Override
public void signal() {
lock.lock();
try {
condition.signal();
} finally {
lock.unlock();
}
}
}
I also have extended FutureTask to expose the set method, as follows:
class MyFutureTask<V> extends FutureTask<V> {
private MyCallable<V> myCallable;
public MyFutureTask(MyCallable<V> r) { super(r); myCallable = r;}
#Override
public void set(V x) { super.set(x); }
#Override
public void setException(Throwable t) { super.setException(t); }
#Override
protected void done() {
super.done();
myCallable.signal();
}
}
When the task is done, I signal the callable to stop it.
So every time a send is called, I create a new MyFutureTask, run it using an executor, save it in a map and return it.
When onMessageReceived is called I find the task in the map and set its result with the set method.
Is this a good approach?
And another question: is it a good approach to move the executor logic inside the task? I mean, to create a start method for it, which will run the task using the executor.
please advice.
I have a threadfactory, executor, thread class and a runnable class.
Here is the thread class: (threadsCount is an AtomicInteger that I use to keep track of number of threads created)
public void run() {
try {
threadsCount.incrementAndGet();
super.run();
} finally {
threadsCount.decrementAndGet();
}
}
and my runnable class is currently not implemented but has empty run() method.
When I try to call Executor.execute(new RunnableClazz()), control comes to this Thread class - run() method and when it encounters super.run(), it goes to the RunnableClazz#run() method.
All these are fine. But problem is, after the RunnableClazz#run() is completed, the control doesn't come back to 'finally' block of my Thread class.
Any ideas? Do I need to manully kill the runnable at the end of run() method?
public class ThreadAA extends Thread {
private static final AtomicInteger threadsCount = new AtomicInteger();
private static final AtomicInteger threadsCreated = new AtomicInteger();
public static final String DEFAULT_NAME = "ThreadAA";
public ThreadAA(Runnable r)
{
this(r, DEFAULT_NAME);
}
public ThreadAA(Runnable r, String threadName)
{
super(r, threadName + "-" + threadsCreated.incrementAndGet());
setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
{
public void uncaughtException(Thread t, Throwable e)
{
logger.error("Uncaught exception in thread " + t.getName(), e);
}
});
}
#Override
public void run()
{
boolean debug = false;
//just for debug purpose
debug = true;
if(debug)
{
logger.debug("Running thread " + getName());
}
try
{
threadsCount.incrementAndGet();
super.run();
}
finally
{
threadsCount.decrementAndGet();
if(debug)
{
logger.debug("Done running thread " + getName());
}
}
}
}
My RunnableClass:
public class RunnableClazz implements Runnable {
#Override
public void run() {
logger.debug("Inside RunnableClazz");
}
}
The method that calls this runnable looks like this:
Executor executor = new Executor(25, 100, 1L, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(5), new TFactory("abc"));
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.execute(new RunnableClazz());
executor.execute(new RunnableClazz());
Please note that, I create the executor just once during server startup. I have pasted it just to give an idea on how I create it.
So executor.execute(new RunnableClazz()); creates the issue.
I copied your code and started debugging.
When you call super.run() it runs the one from ThreadPoolExecutor:
public void run() {
runWorker(this);
}
runWorker then calls RunnableClazz.run(), and after that is finished, it puts the thread on hold, waiting for new runnables to be executed. How did this happened?
In the threadFactory, which I assume it's something like this:
public Thread newThread(Runnable r) {
return new ThreadAA(r);
}
the Runnable r is not your RunnableClazz, but the ThreadPoolExecutor.
EDIT:
You may want to extend the ThreadPoolExecutor class and implement the methods:
protected void beforeExecute(Thread t, Runnable r) { }
protected void afterExecute(Runnable r, Throwable t) { }
and implement your counting there.
I have a thread inside a class like this-
import java.util.Observable;
public class Download extends Observable {
private int state = 0;
private final Thread myThread = new Thread(() -> {
/*
some work to do here
*/
setChanged();
notifyObservers(state);
});
public void download(int state) {
if (!myThread.isAlive()) {
this.state = state;
myThread.start();
}
}
public Thread getThread() {
return myThread;
}
public static void MyMethod() throws InterruptedException {
Download down = new Download();
down.addObserver((Observable ob, Object dat) -> {
System.out.println(ob);
if ((int) dat == 1) {
down.download(2);
} else {
System.out.println("success");
}
});
down.download(1);
down.getThread().join();
}
public static void main() throws InterruptedException {
MyMethod();
}
}
The problem is I never get it to print the "success" message.
I assume, it is because all observers are being notified from inside of MyThread. So when down.download(2) is called from the observer inside MyMethod(), the previous thread is still running and the call is ignored.
How can I notify all observers from the main thread, not from the myThread?
You are calling down.download(2) from within the execution of MyThread, therefore the thread is still alive which means that your download method does nothing because of if(!myThread.isAlive()).
I would recommend you to use the Executor framework and Listenable Futures from Guava instead of creating threads manually. Example code from the Guava wiki:
ListeningExecutorService service =
MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
ListenableFuture<Explosion> explosion = service.submit(new Callable<Explosion>() {
public Explosion call() {
return pushBigRedButton();
}
});
Futures.addCallback(explosion, new FutureCallback<Explosion>() {
// we want this handler to run immediately after we push the big red button!
public void onSuccess(Explosion explosion) {
walkAwayFrom(explosion);
}
public void onFailure(Throwable thrown) {
battleArchNemesis(); // escaped the explosion!
}
});
Note that Futures.addCallback(..) also has an overload which allows you to determine which executor should execute the callback, this seems to be what you want.