I'm trying to interrupt active threads created in Restart() using Terminate() they both extend Event(). I have it set up so Terminate would change the value of terminate to true but I can't get the setter to change the value of terminate outside of Terminate():
Here is the relevant code:
Restart.java:
public class Restart extends Event {
...
public void action() {
...
for (int i = 0; i < eventList.size(); i++) {
Class<?> eventClass;
try {
eventClass = Class.forName(eventList.get(i));
Object eventObject;
if (eventList.get(i).equals("Bell")) {
eventObject = eventClass.getConstructor(long.class, int.class).newInstance(timeList.get(i), rings);
}
else {
eventObject = eventClass.getConstructor(long.class).newInstance(timeList.get(i));
}
eventThread = new Thread((Runnable) eventObject);
eventThread.start();
}
catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
Terminate.java
public class Terminate extends Event {
public Terminate(long delayTime) {
super(delayTime);
}
public void action() {
setTerminate(true);
System.out.println(getTerminate());
}
public String toString() {
return "Terminating";
}
}
Event.java
public abstract class Event implements Runnable {
...
public boolean terminate;
...
public void setTerminate(boolean terminate) {
this.terminate = terminate;
}
public boolean getTerminate() {
return terminate;
}
public void run() {
try {
Thread.sleep(delayTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
System.out.println(getTerminate());
while (getTerminate()) {
eventThread.interrupt();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println(this.toString());
this.action();
}
catch (Exception e) {
e.printStackTrace();
}
}
Related
I am building TODO app with room database and MVVM.
So since I can't use ROOM in main thread,I searched for solutions and came across "Callable" which is just what I need!
Since I have more than 5 functions that make database calls, I wonder how I can use the same Callable code instead of writing it 5 times in different functions.
This is how I currently doing it:
public List<Task> getAllUnCompletedTasksAsList() {
Callable<List<Task>> callable = new Callable<List<Task>>() {
#Override
public List<Task> call() throws Exception {
return appDataBase.taskDao().getAllUnCompletedTasksAsList();
}
};
Future<List<Task>> future = Executors.newSingleThreadExecutor().submit(callable);
try {
return future.get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
public List<Task> getCompletedTasksAsList() {
Callable<List<Task>> callable = new Callable<List<Task>>() {
#Override
public List<Task> call() throws Exception {
return appDataBase.taskDao().getCompletedTasksAsList();
}
};
Future<List<Task>> future = Executors.newSingleThreadExecutor().submit(callable);
try {
return future.get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
public List<Task> getWeeklyTasksAsList() {
Callable<List<Task>> callable = new Callable<List<Task>>() {
#Override
public List<Task> call() throws Exception {
return appDataBase.taskDao().getWeeklyTasksAsList();
}
};
Future<List<Task>> future = Executors.newSingleThreadExecutor().submit(callable);
try {
return future.get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
I would love to hear your suggestions,Thank you !
You are instantiating an anonymous inner class. Do it once outside the methods and use the field instance of your Callable.
private Callable<List<Task>> callable = new Callable<List<Task>>() {
#Override
public List<Task> call() throws Exception {
return appDataBase.taskDao().getAllUnCompletedTasksAsList();
}
};
And (for example)
public List<Task> getAllUnCompletedTasksAsList() {
/*
Callable<List<Task>> callable = new Callable<List<Task>>() {
#Override
public List<Task> call() throws Exception {
return appDataBase.taskDao().getAllUnCompletedTasksAsList();
}
};
*/
Future<List<Task>> future = Executors.newSingleThreadExecutor().submit(this.callable);
try {
return future.get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
public class Sample {
public static void main(String[] args) {
method();
}
public static void method()
{
try {
System.out.println("function");
throw new StaleElementReferenceException("thih sexception occured");
}
catch (StaleElementReferenceException e) {
method();
}
catch (Exception e) {
System.out.println("AssertFail");
}
}
}
how to avoid Infinite Recursion in a non-return method with Try catch...For Example this code below...when the StaleElementException Occurs only once i want to execute "functions after Exception , if the Stale Element occurs the second time i want it to go to Exception catch and print Assert fail..how?
public class Sample {
public static void main(String[] args) {
method(false);
}
public static void method(boolean calledFromCatchBlock)
{
try {
System.out.println("function");
if(!calledFromCatchBlock) {
throw new StaleElementReferenceException("thih sexception occured");
} else {
throw new Exception();
}
} catch (StaleElementReferenceException e) {
method(true);
} catch (Exception e) {
System.out.println("AssertFail");
}
}
}
You should store somehow the state when you throw an exception (e.g. a boolean flag) outside method(), check this state and throw modified exception next time:
private static boolean alreadyThrown = false;
public static void method()
{
try {
System.out.println("function");
if (alreadyThrown) {
throw new RuntimeException("another exception occured");
} else {
alreadyThrown = true;
throw new StaleElementReferenceException("this exception occured");
}
}
catch (StaleElementReferenceException e) {
method();
}
catch (Exception e) {
System.out.println("AssertFail");
}
}
Or you could provide some argument to the method(int arg) and check its value in a similar way:
public static void main(String[] args) {
method(1);
}
public static void method(int arg)
{
try {
System.out.println("function");
if (arg > 1) {
throw new RuntimeException("another exception occured");
} else {
throw new StaleElementReferenceException("this exception occured");
}
}
catch (StaleElementReferenceException e) {
method(arg + 1);
}
catch (Exception e) {
System.out.println("AssertFail");
}
}
I have a similar problem as asked here - How to disable Redis Caching at run time if redis connection failed. My application is using #Cacheable at the service layer for most of the database/static resources call.
Cache is backed by Couchbase and whenever application fails to connect Couchbase node application goes down. Which is what we are not expecting, we expect data should be served from the source system whenever connection failed.
We tried implementing CacheErrorHandler but it does not work as expected because we want to execute the actual method which is making a service call and return the response rather than logging the Cache fail, basically bypassing the cache and as soon as the Couchbase node is up or connection established get the data from cache.
Any idea how we can achieve it?
Thanks #Daniel Bickler for the suggestion, below is the implementation I written referring #John Blum answer.
CouchbaseCustomCacheManager:
import java.util.Map;
import org.springframework.cache.Cache;
import com.couchbase.client.spring.cache.CacheBuilder;
import com.couchbase.client.spring.cache.CouchbaseCacheManager;
public class CouchbaseCustomCacheManager extends CouchbaseCacheManager {
public CouchbaseCustomCacheManager(
final Map<String, CacheBuilder> initialCaches) {
super(initialCaches);
}
#Override
public Cache getCache(String name) {
return new CouchbaseCacheWrapper(super.getCache(name));
}
protected static class CouchbaseCacheWrapper implements Cache {
private final Cache delegate;
public CouchbaseCacheWrapper(Cache couchbaseCache) {
this.delegate = couchbaseCache;
}
#Override
public String getName() {
try {
return delegate.getName();
} catch (Exception e) {
return null;
}
}
#Override
public Object getNativeCache() {
try {
return delegate.getNativeCache();
} catch (Exception e) {
return null;
}
}
#Override
public ValueWrapper get(Object key) {
try {
return delegate.get(key);
} catch (Exception e) {
return null;
}
}
#Override
public <T> T get(Object key, Class<T> type) {
try {
return delegate.get(key, type);
} catch (Exception e) {
return null;
}
}
#Override
public void put(Object key, Object value) {
try {
delegate.put(key, value);
} catch (Exception e) {
try {
handleErrors(e);
} catch (Exception e1) {
}
}
}
#Override
public ValueWrapper putIfAbsent(Object key, Object value) {
try {
return delegate.putIfAbsent(key, value);
} catch (Exception e) {
return null;
}
}
#Override
public void evict(Object key) {
try {
delegate.evict(key);
} catch (Exception e) {
try {
handleErrors(e);
} catch (Exception e1) {
}
}
}
#Override
public void clear() {
try {
delegate.clear();
} catch (Exception e) {
try {
handleErrors(e);
} catch (Exception e1) {
}
}
}
protected <T> T handleErrors(Exception e) throws Exception {
if (e instanceof Exception) {
return null;
} else {
throw e;
}
}
}
}
And used it as:
#Bean
public CacheManager cacheManager() {
final Map<String, CacheBuilder> cache = new HashMap<>();
for (final String appCache : "127.0.0.1,127.0.0.2,127.0.0.3".split(",")) {
cache.put(appCache, CacheBuilder.newInstance(CouchbaseCluster.create().openBucket(
"default", "")));
}
return new CouchbaseCustomCacheManager(cache);
}
The Future object is never able to obtain access to the synchronized block of code so it never finishes and never returns. There isn't anything accessing writeOut() besides the thread so I am not sure why it is block.
public class FileManager {
private void writeOut() throws BusinessException {
if(f.exists() && f.canWrite()) {
synchronized (this) {
try (FileWriter fileWriter = new FileWriter(f)) {
String endLine = "\n";
fileWriter.write("");
for (Entry entry : directory) {
fileWriter.append(entry.getLastName());
fileWriter.append(CSV_DELIMITER);
fileWriter.append(entry.getFirstName());
fileWriter.append(CSV_DELIMITER);
fileWriter.append(entry.getPhoneNumber());
fileWriter.append(CSV_DELIMITER);
fileWriter.append(entry.getAddress());
fileWriter.append(endLine);
}
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
System.out.println(f.getAbsolutePath() + " doesn't exist or can't be written to");
}
}
public void addEntry(Entry entryModel, boolean notify) {
assert entryModel != null;
synchronized (this) {
AddEntryAction addAction = new AddEntryAction(entryModel, notify);
AddEntryActor actor = new AddEntryActor(addAction);
actor.execute();
deleteActor(actor);
}
}
Here is the method that is called by execute():
private void executeAsynchronously() {
Callable<String> asyncTask = () -> {
try {
ServiceFw.fileManager.writeBack();
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BusinessException e) {
notifyFailure();
}
return "write back operation";
};
future = executor.submit(asyncTask);
Runnable poll = () -> {
if(future!=null) {
notifySuccess();
} else {
notifyFailure();
}
};
poll.run();
}
I am using an actionListener to trigger an sequence of events and ultimatley this code is called:
public class ScriptManager {
public static Class currentScript;
private Object ScriptInstance;
public int State = 0;
// 0 = Not Running
// 1 = Running
// 2 = Paused
private Thread thread = new Thread() {
public void run() {
try {
currentScript.getMethod("run").invoke(ScriptInstance);
} catch(Exception e) {
e.printStackTrace();
}
}
};
public void runScript() {
try {
ScriptInstance = currentScript.newInstance();
new Thread(thread).start();
State = 1;
MainFrame.onPause();
} catch (Exception e) {
e.printStackTrace();
}
}
public void pauseScript() {
try {
thread.wait();
System.out.println("paused");
State = 2;
MainFrame.onPause();
} catch (Exception e) {
e.printStackTrace();
}
}
public void resumeScript() {
try {
thread.notify();
System.out.println("resumed");
State = 1;
MainFrame.onResume();
} catch (Exception e) {
e.printStackTrace();
}
}
public void stopScript() {
try {
thread.interrupt();
thread.join();
System.out.println("stopped");
State = 0;
MainFrame.onStop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The runnable is created and ran, however, the problem occurs when I try to use the any of the other methods, they lock my UI. (I'm assuming this is because im running this on the EDT) Does anyone know how to fix this?
That's not how you use wait and notify. They need to be executed on the thread that you are trying to pause and resume. Which means you need to send a message to the other thread somehow. There are various ways to do this, but the other thread needs to be listening for this message, or at least check for it occassionally.