Use semaphore to stop thread in timer from execution - java

I have the following java code, that uses the ScheduledExecuterService. Basically, there are two important calls made in this method: 1. the integrationMonitor.Processor(...) and 2. the runIntegrationSynching() methods.
The scheduler will make sure that these methods execute according to the time interval. Recently however, I've had the problem where processing of these two methods are very long. If the user then sets the timer interval to too low, the next processing cycle will start, even before the previous one finished.
Someone here suggested I use semaphores to do the synchronization, and I did - it works for one of my test cases, but not the other one.
I am using a semaphore to prevent a new schedule cycle to start, if a previous one is still busy. How can I know when a thread finished so that I can release the semaphore?
Here is the code:
static Semaphore semaphore = new Semaphore(1);
final ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
try {
semaphore.acquire();
catch(InterruptedException e1) {}
runIntegrationSynching();
try {
semaphore.release();
} catch(InterruptedException e1) {}
Thread thread = new Thread(){
public void run(){
IntegrationMonitor intgrationMonitor = new IntegrationMonitor();
try {
semaphore.acquire();
} catch(InterruptedException e1) {}
intgrationMonitor.Processing(configXML, rcHost, alarmMonitorMap, blocker);
try {
semaphore.release();
} catch(InterruptedException e1) {}
if(intgrationMonitor != null){
intgrationMonitor = null;
}
}
};
LOGGER.info("Attempting to start the thread for RC " + rcHost + ". Thread ID:" + thread.getId());
thread.start();
}
},2,2,TimeUnit.MINUTES);

Related

Android Thread is not timing out on wait/notify method

The timeout on b.wait(1000) instruction is not executing after 1 second.
I will appreciate some help on how to execute the timeout on the wait() method.
protected void onCreate(Bundle savedInstanceState) {
ThreadB b = new ThreadB();
b.start();
synchronized (b) {
try {
long start = System.currentTimeMillis();
Log.i(TAG, "Before Wait has started "+start);
b.wait(1000);
long finish = System.currentTimeMillis();
Log.i(TAG, "After Wait has finished "+finish);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
}
class ThreadB extends Thread {
#Override
public void run() {
synchronized (this) {
long start = System.currentTimeMillis();
Log.i(TAG, "*** Thread Start "+start);
Random ran = new Random();
for (int i = 0; i < 1E7; i++) {
Math.sin(ran.nextDouble());
}
long finish = System.currentTimeMillis();
Log.i(TAG, "*** Thread Finish "+finish);
notify();
}
}
}
Your program has a "race" to acquire the lock on the ThreadB object. If the main thread wins the race, the timeout logic works. If the new thread wins, the main thread has to wait for the new thread to finish so that it can grab the lock, and after that then it will call Object.wait and sleep for 1 second.
One quick fix is to make sure that the main thread has the lock before the new thread starts:
ThreadB b = new ThreadB();
synchronized (b) {
b.start();
try {
long start = System.currentTimeMillis();
....
}
}
A better solution is to start using the higher level concepts in the java.util.concurrent library. Instead of creating a new thread, send a task to be computed by a thread pool:
ExecutorService threadPool = Executors.newFixedThreadPool(1);
Future<?> submit = threadPool.submit(() -> {
// ThreadB computation logic
});
and then specify a timeout to wait for its results:
try {
submit.get(1, TimeUnit.SECONDS);
} catch (Exception e) {
// handle timeout, interruption, exceptions
}
Note that on Android, it's not a great idea make the main thread block or wait, even if it's for only 1 second.

Safe thread utilization

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.

Java - Get thread state

I am using ThreadPoolExecutor to run the threads.
ExecutorService executorService = Executors.newCachedThreadPool();
Future<?> future = executorService.submit(new MyRunnable());
Based on some conditions, I need to terminate the long running thread and start the same thread instance again(for some cleanup operations).
Since I have a future object of the thread, I can easily check if it is still running.
future.isDone()
If it is running, I can send a interrupt signal by using
future.cancel(true);
In the MyRunnable class, the interrupt signal is handled. But this condition is checked at the beginning of the loop.
The problem is future.isDone() returns true as soon as interrupt signal is sent. But I need to wait till the thread instance is really completed.
Is there any way to check if the thread is really running/completed?
The Apidoc also mentions that future.isDone() returns true if future.cancel() was called, i.e. it does not always tell you if the task has finished.
To check if the task is finished, you need acces to the Runnable and then you can check if the task has completed or wait for it to complete.
Compare the code below with the output shown beneath it, I think that will give you an idea of your options:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Q21227864 {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
Future<?> future = executorService.submit(new MyRunnable());
sleep(100L);
future.cancel(true);
System.out.println("Future done: " + future.isDone());
sleep(100L);
future.cancel(true);
System.out.println("Future done: " + future.isDone());
sleep(500L);
System.out.println("Future done: " + future.isDone());
System.out.println("---");
MyRunnable mr = new MyRunnable();
future = executorService.submit(mr);
sleep(100L);
future.cancel(true);
System.out.println("Runnable done: " + mr.isDone());
sleep(100L);
System.out.println("Runnable done: " + mr.isDone());
mr.waitForCleanup();
System.out.println("Runnable done: " + mr.isDone());
executorService.shutdownNow();
}
public static void sleep(long timeMs) {
try { Thread.sleep(timeMs); } catch (Exception ignored) {}
}
static class MyRunnable implements Runnable {
final CountDownLatch completed = new CountDownLatch(1);
public void run() {
try {
System.out.println("Sleeping loop");
Thread.sleep(1000L);
System.out.println("Sleeping loop done");
} catch (Exception e) {
System.out.println("Stopped loop: " + e);
}
try {
System.out.println("Sleeping cleanup");
Thread.sleep(300L);
System.out.println("Sleeping cleanup done");
} catch (Exception e) {
System.out.println("Stopped cleanup: " + e);
}
completed.countDown();
}
public boolean isDone() {
return (completed.getCount() == 0);
}
public void waitForCleanup() {
try { completed.await(); } catch (Exception ignored) {}
}
}
}
Output:
Sleeping loop
Future done: true
Stopped loop: java.lang.InterruptedException: sleep interrupted
Sleeping cleanup
Future done: true
Sleeping cleanup done
Future done: true
---
Sleeping loop
Runnable done: false
Stopped loop: java.lang.InterruptedException: sleep interrupted
Sleeping cleanup
Runnable done: false
Sleeping cleanup done
Runnable done: true
I don't think future.isDone() returns true as soon as interrupt signal is sent. All ThreadPoolExecutor tasks are executed via FutureTask.run() method
public class FutureTask<V> implements RunnableFuture<V> {
...
public boolean isDone() {
return state != NEW;
}
public void run() {
...
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call(); <-- this invokes your code
ran = true;
} catch (Throwable ex) {
result = null; <-- if you threw InterruptedException
ran = false;
setException(ex); <-- state changes here
}
if (ran)
set(result); <-- if your code simply returns then state changes here
}
...

How to stop a thread whose run() doesnt have a loop

How to stop a thread whose run() doesnt have a loop.
So basically I want a replacement for the stop() method.
I want to stop one of the Thread when there is a deadlock.
I dont want to use locks. Just want to kill one thread so that the resource will be freed and other Thread will continue thus ending the program.
I tried still using stop() but even that is not stopping the program.
Following is my code:-
public class Deadlock {
public static boolean stop = false;
public static void main(String[] args) {
final String resource1 = "resource1";
final String resource2 = "resource2";
// t1 tries to lock resource1 then resource2
Thread t1 = new Thread() {
public void run() {
// Lock resource 1
synchronized (resource1) {
System.out.println("Thread 1: locked resource 1");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
synchronized (resource2) {
System.out.println("Thread 1: locked resource 2");
}
}
}
};
// t2 tries to lock resource2 then resource1
Thread t2 = new Thread() {
public void run() {
synchronized (resource2) {
System.out.println("Thread 2: locked resource 2");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
synchronized (resource1) {
System.out.println("Thread 2: locked resource 1");
}
}
}
};
// If all goes as planned, deadlock will occur,
// and the program will never exit.
t1.start();
t2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(t1.isAlive() && t2.isAlive())
{
System.out.println("Deadlock");
// t1.stop(); Deprecated
}
}
}
You can't fix a bug other than by actually fixing the bug. If a thread has a bug, the bug has to be fixed or it will contaminate the process context.
See this answer for just one of the reasons it's not safe to reach into a thread from the outside and release its locks. Also, the link in dst's comment is very helpful.

How to make a Java thread hang

I am trying to create a solution to treat hung threads due to memory leaks, locked resources in our applications. One of the main problems I am having is trying to simulate a hung thread to deal with it. Any sugestions?
This is what I tried, but it just doesn't seem to do the job. Any thoughts?
class KillerThread extends Thread{
public KillerThread() {
super();
}
public KillerThread(String threadName) {
super(threadName);
}
public void run (){
System.out.println("Start of KillerThread " + this.getName() );
if ( System.currentTimeMillis() % 2L == 0 ){
try {
sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
for(;;);
}
}
}
Joining on one's own thread works well for me:
Thread.currentThread().join();
try running sleep in a while loop like:
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
running a thread then tell it to sleep in an unstoppable loop, is a good idea,.
but how if you are trying to make it waiting another thread,.? make more than one thread and make them wait one each other, a deadlock condition, is that a hung to,.?
I know what you need exactly, you are testing something through stopping the executor thread. Try something like this:
private void testKillingThread() {
Object kill = new Object();
try {
synchronized (kill) {
kill.wait();
}
} catch (Exception e) {
// Auto-generated catch block
}
}
Simply enough, just create a private member
private Object lock = new Object();
then use it to wait for a notification (that will never happen, unless you use reflection...)
while (true) {
try {
synchronized (lock) {
lock.wait();
}
} cath (InterruptedException e) {
/* ignore interruption */
}
}
and you thread will hang there, uninterruptable.
Here's a quick fix I'm using for testing. Just have the thread you want to lock up call new Hanger().hang().
Remove the logging if you're not interested in seeing it. You can add throws InterruptedException (although, in fact, it never does) to the hang method so you can just replace a Thread.sleep() with a new Hanger().hang() without otherwise modifying your code.
public class Hanger {
private final static Logger log = Logger.getLogger(Hanger.class);
private long started = 0;
private final int beat = 100; // ms
/**
* Hangs a thread for the indicated time
* #param millis the amount of time to hang the thread, in milliseconds
*/
public void hang(int millis) {
started = System.currentTimeMillis();
log.debug("Hanging this thread for " + millis + " ms");
while (hung() < millis) {
try {
Thread.sleep(beat);
} catch (InterruptedException e) {
log.debug("Still hanging, will release in " + (millis - hung()) + " ms.");
}
}
log.debug("Releasing thread again after " + hung() + " ms");
}
private int hung() {
return (int)(System.currentTimeMillis() - started);
}
}

Categories