I have a requirement threading where I need to initiate a thread which will run continuously doing some DB operations . A second thread will be present which needs to run for every 30 secs. The job of the second thread will be killing the first thread and start a new instance of the first thread.
I tried several ways to achieve this but I am not able to do the same.
public class ThreadMain {
public static void main(String[] args) throws InterruptedException, BrokenBarrierException{
final CyclicBarrier gate = new CyclicBarrier(3);
Thread t1 = new Thread(){
public void run(){
try {
gate.await();
while(true)
{
System.out.println("Thread1");
break;
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}};
Thread t2 = new Thread(){
public void run(){
try {
gate.await();
while(true)
{
System.out.println("Continiously running thread:-Thread2");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}};
t1.start();
t2.start();
This seems to work nicely:
// Thread that runs forever.
volatile static Thread forEverThread = null;
static class ForEver implements Runnable {
#Override
public void run() {
try {
while (true) {
Thread.sleep(1000);
System.out.println("For Ever!");
}
} catch (InterruptedException ex) {
// Just quit if I was interrupted.
}
}
}
// Stop the thread if it is running.
private static void stopForeverThread() throws InterruptedException {
// Skip if non-existent.
if (forEverThread != null) {
// Make sure no-one else is already doing it.
synchronized (forEverThread) {
// Still not null?
if (forEverThread != null) {
// Interrupt it.
forEverThread.interrupt();
// Wait for it to finish.
forEverThread.join();
// Clear it.
forEverThread = null;
}
}
}
}
private static void restartForeverThread() throws InterruptedException {
System.out.println("Restarting...");
// Stop it if it is running.
stopForeverThread();
// Start it again.
forEverThread = new Thread(new ForEver());
forEverThread.start();
System.out.println("Restarted");
}
public static void start() throws InterruptedException {
// Start it all up.
restartForeverThread();
// Timed event to restart it.
Timer restartTimer = new Timer(true);
restartTimer.scheduleAtFixedRate(
new TimerTask() {
#Override
public void run() {
try {
// Restart every few seconds.
restartForeverThread();
} catch (InterruptedException ex) {
// We were interrupted during restart - Log it.
}
}
// Every few seconds.
}, 0, 10 * 1000);
}
public static void main(String args[]) {
try {
// Start it all up.
start();
// Hang around for a while - to see what happens.
Thread.sleep(60 * 1000);
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
If your database task is interruptible (i.e. it reacts on thread interruption and hence can be cancelled by that), the best strategy is to use an ScheduledExecutorService for both, the database task itself and the restart task that runs periodically.
Note that task and thread are two different things: While a task is a piece of work that should be run, threads are the mechanism to do this in parallel.
static class DatabaseTask implements Runnable {
public void run() {
...
}
}
static class RestartTask implements Runnable {
private final ExecutorService executor;
private volatile Future<Void> future;
public RestartTask(ExecutorService executor) {
this.executor = executor;
}
public void run() {
if (future != null) {
future.cancel(true);
}
future = executor.submit(new DatabaseTask());
}
}
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(new RestartTask(executor), 0, 30, TimeUnit.SECONDS);
Note that if your DatabaseTask is NOT sensitive to thread interruption and continues to perform database operations, the number of threads executing database tasks will grow continously - probably not what you want. So make sure, all blocking database operations are either interruptible, or terminate within a reasonable amount of time.
Related
ScheduledExecutorService is still running after calling its shutdown methos from class's shutdown method below.
I was not expecting to see perioudRun's call after shutdown
Running the method shutdown
Running the method periodicRun-
What should I do ensure, the schedule run is cancelled ?
class test {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
test() {
scheduler.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
funcA("periodicRun-");
}
}, 15, 15, TimeUnit.SECONDS);
}
private void funcA(String path) {
LOGGER.info("Running the method " + path)
}
public void shutdown() {
long startTimeMs = System.currentTimeMillis();
scheduler.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!scheduler.awaitTermination(initialTerminationSeconds, TimeUnit.SECONDS)) {
scheduler.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
scheduler.awaitTermination(retryTerminationSeconds,
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
scheduler.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
funcA("shutdown-");
}
}```
The code you provided does not compile. I made some corrections and some assumptions where it did not compile, and the following code works as expected, i.e. "periodicRun" is not printed after shutdown() is called:
class Test {
public static void main(String[] args) {
Test test = new Test();
test.test(); // CALL TEST METHOD
Thread t = new Thread(() -> {
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
test.shutdown(); // CALL SHUTDOWN METHOD
});
t.start();
}
private final int initialTerminationSeconds = 1;
private final int retryTerminationSeconds = 1;
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
void test() {
scheduler.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
funcA("periodicRun-");
}
}, 15, 15, TimeUnit.SECONDS);
}
private void funcA(String path) {
System.out.println("Running the method " + path);
}
public void shutdown() {
long startTimeMs = System.currentTimeMillis();
scheduler.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!scheduler.awaitTermination(initialTerminationSeconds, TimeUnit.SECONDS)) {
scheduler.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
scheduler.awaitTermination(retryTerminationSeconds, TimeUnit.SECONDS);
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
scheduler.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
funcA("shutdown-");
}
}
As this code works as expected, the problem in your code is either somewhere else or the assumptions and corrections I made to your code are incorrect.
I am learning multithreading.
I tried to implement producer consumer problem in Java.Its working fine.
But if i remove notify call the program goes into a deadlock state.Why?
Its going on deadlock when size of queue becomes 0.Ideally when size becomes 0,wait should be called inside consumer and producer should started working.
import java.io.*;
import java.util.*;
class Consumer implements Runnable{
Queue<Integer> q;
int n;
public void run() {
while(true){
synchronized (q) {
while(q.size()==0){
try {
System.out.println("q.size="+q.size());
q.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("item consumed="+q.poll());
q.notify();
try {
Thread.sleep((int)(Math.random() * 100));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Consumer(Queue<Integer> queue,int n){
q=queue;
this.n=n;
}
}
class Producer implements Runnable{
Queue<Integer> q;
int n;
public void run() {
int x=1;
while(true){
synchronized (q) {
while(q.size()==n){
try {
q.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("item produced="+x+" q.size="+q.size());
q.add(x++);
q.notify();
try {
Thread.sleep((int)(Math.random() * 100));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Producer(Queue<Integer> queue,int n){
q=queue;
this.n=n;
}
}
public class App
{
public static void main( String[] args ) throws InterruptedException
{
int n=100;
Queue<Integer> q=new LinkedList<Integer>();
Thread t1=new Thread(new Producer(q, n));
Thread t2=new Thread(new Consumer(q, n));
t1.start();
t2.start();
t1.join();
t2.join();
}
}
you required notify because when one thread is on wait state because queue is empty or full come to running state if some other thread notify after putting if queue is empty and taking queue is full.
put q.wait(10); so your code will not go on deadlock because after time it will check while loop condition.
It is always best practice to use notify in above usecase
I am using single thread executor for long-running threads like this:
executor = Executors.newSingleThreadExecutor(THREAD_FACTORY);
executor.submit(new LongRunnable());
which checks a flag to be stopped:
private class LongRunnable implements Runnable {
#Override
public void run() {
while (isRunning.get()) {
try {
doSomething();
} catch (InterruptedException e) {
...
}
}
}
}
and whole execution is interrupted that way:
#Override
public void close() throws Exception {
isRunning.set(false);
executor.shutdownNow();
}
Still I can see some threads not gc-ed in profiler (while by logs, runnable they were executing has quit outermost while loop).
Question: does provided working with threads strategy memory-leak-free and thread-leak-free?
I am not able to see any issue with executor or shutDownNow. Probably you are looking at different threads in your profiler.
Try this program which is similar to the one in your question and you can see the thread is no longer there after successful shutdown.
public class ExecutorShutdownTest {
private static ExecutorService executor;
private static AtomicLong executorThreadId = new AtomicLong(0);
public static void main(String[] args) {
// get thread MX bean
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
// create an executor and start the task
executor = Executors.newSingleThreadExecutor(new TestThreadFactory());
LongRunnable runnable = new LongRunnable();
executor.submit(runnable);
// main thread: keep running for sometime
int count = 5;
while (count-- > 0) {
try {
Thread.sleep(1000);
System.out.println(String.valueOf(threadMXBean.getThreadInfo(executorThreadId.longValue())).replace("\r", "").replace(
"\n", ""));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// main thread: stop the task
try {
runnable.close();
System.out.println(String.valueOf(threadMXBean.getThreadInfo(executorThreadId.longValue())).replace("\r", "").replace("\n", ""));
} catch (Exception e) {
e.printStackTrace();
}
// main thread: run some more time to verify the executor thread no longer exists
count = 5;
while (count-- > 0) {
try {
Thread.sleep(1000);
System.out.println(String.valueOf(threadMXBean.getThreadInfo(executorThreadId.longValue())).replace("\r", "").replace("\n", ""));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static class LongRunnable implements Runnable {
private volatile boolean isRunning = true;
#Override
public void run() {
while (isRunning) {
System.out.println("Running");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//ignore
}
}
System.out.println("Stopped");
}
public void close() throws Exception {
System.out.println("Stopping");
isRunning = false;
executor.shutdownNow();
}
}
private static class TestThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
TestThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0) {
#Override protected void finalize() throws Throwable {
super.finalize();
// probably bad idea but lets see if it gets here
System.out.println("Executor thread removed from JVM");
}
};
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
executorThreadId.set(t.getId());
System.out.println("Executor thread created");
return t;
}
}
}
Here's a sample program using the single-thread Executor that manages to strand a thread so that the JVM can't shut down, but it only manages to do it by not calling shutdownNow:
import java.util.concurrent.*;
public class Exec {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(new MyTask());
Thread.sleep(20000L);
// executor.shutdownNow();
int retryCount = 4;
while (!executor.isTerminated() && retryCount > 0) {
System.out.println("waiting for tasks to terminate");
Thread.sleep(500L);
retryCount -= 1;
}
}
}
class MyTask implements Runnable {
public void run() {
int count = 0;
try {
while (!Thread.currentThread().isInterrupted() && count < 10) {
Thread.sleep(1000L);
count += 1;
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("all done");
}
}
The thread used by the executor has a separate life cycle from the task, this example shows how the task finishes but the thread goes on. Uncommenting the shutdownNow results in the executor's thread terminating. Otherwise the main thread sleeps for a while and exits, leaving the executor's thread hanging out, preventing the JVM from exiting.
My guess is that your close method isn't getting called and your executor never gets shut down. To get more useful answers please add a MVCE so that we can reproduce the problem.
Consider that with interruption there's no need to keep a reference to the Runnable to set the flag. As I read the question the task not finishing is not an issue here, but it would still be better to make the Runnable respond to interruption and lose the flag, just because having less things to keep track of is always an improvement.
i'm trying create a thread, which return a value, the process is running correctly but my screen is still locked. I want a thread that return a value but my main thread continues running.
I've done that:
public void showPartidas(int maximumDistance){
ExecutorService es = Executors.newFixedThreadPool(1);
Future<ArrayList<Partida>> partidas= es.submit(new FilterPartidas(maximumDistance));
try {
loadInListView(partidas.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
es.shutdown();
}
class FilterPartidas implements Callable<ArrayList<Partida> > {
private final int distance;
private ArrayList<Partida> partidas;
FilterPartidas(int distance) {
this.distance = distance;
}
#Override
public ArrayList<Partida> call() throws Exception {
partidas=null;
Download load = new Download();
Date fecha = new Date();
DateFormat fechaFormat = new SimpleDateFormat("yyyy-MM-dd");
String query = "select * from partidas where fecha >='"+fechaFormat.format(fecha)+"'";
partidas=load.obtainPartidas(query, distance, myPosition);
return partidas;
}
}
partidas.get() action is the cause that main thread is waiting for the completion of Callable method in executor. If you want main thread are still running during Callable action execution you must place partidas.get() action into dedicated separate thread e.g.:
replace
Future<ArrayList<Partida>> partidas= es.submit(new FilterPartidas(maximumDistance));
try {
loadInListView(partidas.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
into
final Future<ArrayList<Partida>> partidas= es.submit(new FilterPartidas(maximumDistance));
new Thread(new Runnable() {
#Override
public void run() {
try {
loadInListView(partidas.get());
} catch (InterruptedEArrayList<Partida>xception e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}).start();
or similar action with threads (maybe using executor, Runnable, etc).
Or you can change you logic (if possible) and hide call to method from Callable into Runnable class. E,g.:
ExecutorService es = Executors.newFixedThreadPool(1);
es.submit(new Runnable() {
#Override
public void run() {
ArrayList<Partida> partidas = logic from you Callable call;
loadInListView(partidas);
}
});
I want to create long-running application for performing various tasks on different threads. Each task should have one-minute timeout. Here is my implementation:
runner = new Thread(new Runnable() {
#Override
public void run() { }
// some actions here
});
runner.start();
startJoin = System.currentTimeMillis();
runner.join(TIMEOUT);
stopJoin = System.currentTimeMillis();
if ((stopJoin - startJoin) >= TIMEOUT)
throw new TimeoutException("Timeout when reading the response from process");
In general case it is working and throwing TimeoutExceptions, but sometimes it is doing nothing after even few hours. So the questions is if Thread.join is reliable on Android?
I have an idea to use Thread.wait and notify instead of that, what is the better way in your opinion?
Refer below program.
public static void main(String[] args) throws InterruptedException {
long TIMEOUT=100;
Thread runner = new Thread(new Runnable() {
#Override
public void run() {
for(;;){
System.out.println("running ");
}
}
// some actions here
});
runner.start();
long startJoin = System.currentTimeMillis();
runner.join(TIMEOUT);
long stopJoin = System.currentTimeMillis();
if ((stopJoin - startJoin) >= TIMEOUT)
try {
throw new Exception("Timeout when reading the response from process");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Running Thread");
}
This program never ends that means your logic is incorrect.
Better to use TimerTask.
I prefer doing all time base task using Timer and TimerTask. Check the following code and probably this should be useful to you:
Timer t =new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
//The task you want to perform after the timeout period
}
}, TIMEOUT);
EDIT
I am giving a try at solving your problem. I am using the code written by #amicngh as my base code and have done some modifications to it. I presume that after the TIMEOUT period you want to close the running thread. Check the following code runs fine and the explanation that follows:
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
final long TIMEOUT=100;
final long startJoin = System.currentTimeMillis();
Thread runner = new Thread(new Runnable() {
long stopJoin;
#Override
public void run() {
try{
for(;;){
System.out.println("running ");
stopJoin = System.currentTimeMillis();
if ((stopJoin - startJoin) >= TIMEOUT){
throw new Exception();
}
}
}
catch (Exception e) {
// TODO: handle exception
}
}
// some actions here
});
runner.start();
synchronized (ThreadTest.class) {
ThreadTest.class.wait(TIMEOUT);
}
/*if ((stopJoin - startJoin) >= TIMEOUT)
try {
throw new Exception("Timeout when reading the response from process");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
System.out.println("Running Thread");
}
}
The Thread API description says that it is unsafe to destroy or stop (hence both these method has been deprecated) and one of the way to stop a thread is to throw an exception. Hence I am checking for the Timeout inside the runner thread. Now about making the Main thread wait it is done by the 2 lines of code which uses synchronized to synchronize the access to the thread.
Hope this code and explanation solves your problem.