Threads in Cached Thread Pool never being removed - java

So, I have a server like this:
public class Server {
private ExecutorService executor = null;
private class WorkerThread implements Runnable{
public void run() {
try{
do{
synchronized(executor){
executor.wait();
}
// doSomeThing
}while(true);
} catch (InterruptedException e) {
}
}
}
Server() {
executor = Executors.newCachedThreadPool();
}
public void calledWhenTriggerEventOccurs(){
synchronized(executor) {
executor.execute(new WorkerThread());
executor.notify();}
}
}
After calledWhenTriggerEventOccurs() is called for 3 times in a row, 3 new threads are being placed in the executors pool. Then I just wait for 90 sec.
I now would expect the previous 3 threads to be dead. But they are still alive.
When I call calledWhenTriggerEventOccurs() once again a 4th thread is being created.
So why are those 3 threads not being removed as I would expect?

Your tasks most likely wait forever so I wouldn't expect them to die, no matter how long you wait. When you notify() and there isn't any threads waiting the notify is lost. Most likely you have notified three times before your three tasks have a chance to start.

Related

How can I implement this concurrent structure without the queue?

I have a situation in my application where events come in and the thread that handles them (signalling thread) must signal to another thread (working thread), thus far in an idle state, that it can run some code. Once the working thread is done it should wait to be signalled again. It is possible that events will arrive while the working thread is working. In this case it should move on and keep working immediately. One action by the working thread does enough work for any amount of incoming events, so there is no need to work once per event, just once as soon as possible after each event. Example correct behavior:
event comes in
worker thread starts work
worker thread finishes work
event comes in
worker thread starts work
event comes in
event comes in
worker thread finishes work
worker thread starts work
worker thread finishes work
4 events, 3 periods of work. It's an unfortunate but unavoidable requirement that the signalling thread cannot block while handling the event. I have implemented this at the moment using a BlockingQueue, which has the pointless side effect of filling itself up even though the contents are not interesting or even looked at. I was expecting to be able to make this work using CountDownLatch or CyclicBarrier or similar but I haven't been able to find a way. Here is my implementation:
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
public class Main {
private static final class MyBarrier {
private BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
void await() throws InterruptedException {
queue.take();
queue.clear();
}
void signal() {
queue.add(true);
}
}
private static Random random = new Random(0);
private static void sleepForMax(int maxMillis) {
sleep(random.nextInt(maxMillis));
}
private static void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public static void main(String[] args) {
MyBarrier myBarrier = new MyBarrier();
final ExecutorService singallingThread = Executors.newSingleThreadExecutor();
singallingThread.submit(() -> {
while (!Thread.currentThread().isInterrupted()) {
sleepForMax(1_000); // simulate period between events arriving
myBarrier.signal();
System.out.println("Signalling work to be done");
}
System.out.println("Thread interrupted");
});
final ExecutorService workingThread = Executors.newSingleThreadExecutor();
workingThread.submit(() -> {
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.println("Waiting for work");
myBarrier.await();
} catch (InterruptedException e) {
break;
}
System.out.println("Doing work...");
sleepForMax(3_000); // simulate work being done
System.out.println("Work done");
}
System.out.println("Thread interrupted");
});
sleep(10_000);
singallingThread.shutdownNow();
workingThread.shutdownNow();
}
}
What's the better way to do this?
When I run your code with your implementation that uses Phaser, having changed the sleep times so that signalling occurs every 800 ms and processing takes 1000 ms, I get e.g. this output:
00008: Waiting for work
00808: Signalling work to be done
00808: Doing work... <-- worker starts working
01608: Signalling work to be done <-- signal came, so there's more work
01808: Work done
01809: Waiting for work <-- waits for work...
02409: Signalling work to be done <-- ...for 600 ms, until the next signal
02409: Doing work...
(The number to the left is milliseconds since start. Also, you can reproduce it with your code with random delays, but that's harder to reproduce and see there.)
If I understood it correctly, this is wrong. E.g. imagine what happens if signals stop coming.
Your code can probably work with this adjustment for your specific case:
private static final class MyBarrierWithPhaser {
private final Phaser phaser = new Phaser(1);
private int lastObservedPhase; // Phaser has initial phase 0
void await() throws InterruptedException {
// only works for 1 producer 1 worker; lastObservedPhase is kind of thread-local
lastObservedPhase = phaser.awaitAdvanceInterruptibly(lastObservedPhase);
}
void signal() {
phaser.arrive();
}
}
With this, the worker records the last phase it advanced to, and if the signal thread "arrives" before the next awaitAdvanceInterruptibly, then the Phaser phase gets updated, and when worker tries to wait using a stale phase, it will progress immediately; if the signal thread does not arrive before awaitAdvanceInterruptibly, then the worker will wait until the signal thread finally arrives.
Using simpler synchronization primitives, I can think of how to implement it using the synchronized-wait()-notify() mechanism:
private static final class MyBarrierWithSynchronized {
private boolean hasWork = false;
synchronized void await() throws InterruptedException {
while (!hasWork) {
wait();
}
hasWork = false;
}
synchronized void signal() {
hasWork = true;
notifyAll(); // or notify() if we are sure there is 1 signal thread and 1 worker thread
}
}
It has a couple of drawbacks: await() won't be interrupted if the thread is waiting to enter it. Also, some don't like synchronizing on this, I kept it so in order to be short. This can be rewritten using the java.util.concurrent.* analogues, this implementation will not have both of these drawbacks:
private static final class MyBarrierWithLock {
private boolean hasWorkFlag = false;
private final Lock lock = new ReentrantLock();
private final Condition hasWorkCond = lock.newCondition();
void await() throws InterruptedException {
lock.lockInterruptibly();
try {
while (!hasWorkFlag) {
hasWorkCond.await();
}
hasWorkFlag = false;
} finally {
lock.unlock();
}
}
void signal() {
lock.lock();
try {
hasWorkFlag = true;
hasWorkCond.signalAll(); // or signal() if we are sure there is 1 signal thread and 1 worker thread
} finally {
lock.unlock();
}
}
}
I'm experimenting with this, using java.util.concurrent.Phaser, which may work, but I haven't used Phaser before so I'm not sure.
private static final class MyBarrier2 {
private Phaser phaser = new Phaser(1);
void await() throws InterruptedException {
phaser.awaitAdvanceInterruptibly(phaser.getPhase());
}
void signal() {
phaser.arrive();
}
}

Thread won't die and two of them keep overlapping

I need a thread that will only run once at a time, for example if it's called for the first time it will run, if it is called a second time, the first should stop completely and be allowed to die and a new one should take it's place.
I was ran a small test to see what was actually happening between each execution, the results show that the thread doesnt die but instead two threads are being executed alongside:
public class Test {
Worker worker = new Worker();
#Override
public void valid() {
try {
if (worker.running) {
worker.running = false;
worker.join();
}
} catch (InterruptedException iex) {
worker.running = false;
}
worker = new Worker();
worker.start();
}
private final class Worker extends Thread {
private volatile boolean running = true;
#Override
public void run() {
while (running) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException iex) {
Thread.currentThread().interrupt();
}
}
}
}
}
The results are as follows:
//Upon first execution
Thread-4
Thread-4
Thread-4
Thread-4
//When I execute it again
Thread-7
Thread-4
Thread-7
Thread-4
Thread-7
Thread-4
I've tried using ExecutorService or using while(!Thread.currentThread.isInterrupted) instead of the boolean flag, and got the same results.
How can I properly stop "Thread-4" and have only one of them running?
The actual issue comes from a thread that will cycle through a list and update things on discord chat by request, what the thread does is listen to input and change as suggested by kidney I'm trying to use executor.submit() and Future
private ExecutorService executor = Executors.newSingleThreadExecutor();
private Future<Void> worker;
private void setupImageThread() {
if (!worker.isDone() && !worker.isCancelled()) {
worker.cancel(true);
}
this.worker = (Future<Void>)executor.submit(new Cycler(Listener.queue(), this.links, Cel.cMember()));
ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
Runnable timeout = () -> {
executor.shutdown();
};
ses.schedule(timeout, 100, TimeUnit.SECONDS);
}
How can I go about initializing the Future for the first time it is created?
Using single thread executor service, I would try something like this:
public class Test {
private static ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Void> worker;
public Test() {
this.worker = executor.submit(new Worker());
}
#Override
public void valid() {
if (!worker.isDone() && !worker.isCancelled()) {
worker.cancel(true); // Depends on whether you want to interrupt or not
}
this.worker = executor.submit(new Worker());
}
}
And make Worker implement Runnable.
It seems that the method valid can be called several times simultaneously. That means, every of those calls will wait to end only for one thread (Worker), whereas, every of them creates its own Worker and you lose a pointer to it, so it impossible to stop bunch of new created workers.
You should make the valid method synchronized: synchronized void valid() it will prevent creating many workers:
#Override
synchronized public void valid() {
...
}
One more thing to say. You put the while loop outside the try-catch, which is wrong: if the tread gets interrupted, the interruption doesn't kill it, because next interation gets started, so it should be like that:
#Override
public void run() {
try {
while (running) {
System.out.println(Thread.currentThread().getName());
Thread.sleep(2000);
}
catch (InterruptedException iex) {
//you don't need here Thread.currentThread().interrupt() call, because the thread has alredy been interrupted.
// The return statement here is also obsolete, I just use it as an example, but you can use empty braces.
return;
}
}
}

How to end a thread in executor service if thread takes too long?

Sample executor service
static class MyRunnable implements Runnable {
private String serverName;
public MyRunnable(String serverName) {
super();
this.serverName = serverName;
}
#Override
public void run() {
...
conn = new ch.ethz.ssh2.Connection(serverName);
conn.connect();
boolean isAuthenticated = conn.authenticateWithPassword(user, pass);
logger.info("Connecting to " + server);
if (isAuthenticated == false) {
logger.info(server + " Please check credentials");
}
sess = conn.openSession();
...
}
}
public static void main(String[] args) {
List<String> serverList = ...;
ExecutorService executor = Executors.newFixedThreadPool(20);
for (String serverName : serverList) {
MyRunnable r = new MyRunnable(serverName);
executor.execute(r);
}
executor.shutdown();
executor.awaitTermination(1, TimeUnit.HOURS);
}
Right here is a sample code of my executor service. But with this logic when I meet a server that fails to connect or takes too long to connect it creates a a hang time within my application. I want to end/kill the thread if it takes longer than x amount of time to connect. How can I terminate the thread task if it does not connect to server within 2 seconds.
Attempt
ThreadPoolExecutor executor = new ThreadPoolExecutor(
10, 25, 500, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(1));
I added the following code but apparently it does not end the thread if it takes longer than 2000 milliseconds.
Attempt 2
Future<?> future = executor.submit( new task));
try {
future.get(2000, TimeUnit.MILLISECONDS); // This waits timeout seconds; returns null
}
catch(TimeoutException e) {
future.cancel(true);
// System.out.println(server + "name");
}
How can I terminate the thread task if it does not connect to server within 2 seconds.
This is difficult thing to do typically because even if you interrupt the thread (like the other answers mention) there's no guarantee that the thread will stop. Interrupt just sets a flag on the thread and it's up to the code to detect the status and stop. This means that a ton of threads may be in the background waiting for the connects.
In your case however you are using the ch.ethz.ssh2.Connection.connect() method. Turns out there is a connect method that takes a timeout. I think you want the following:
// try to connect for 2 seconds
conn.connect(null, 2000, 0);
To quote from the connect method javadocs:
In case of a timeout (either connectTimeout or kexTimeout) a SocketTimeoutException is thrown.
You have to do awaitTermination() first, then check the return value, and then do shutdownNow(). shutdown() does not guarantee instant stoppage of the service, it just stops taking new jobs, and waits for all jobs to complete in order. shutdownNow() on the other hand, stops taking new jobs, actively attempts to stop all running tasks, and does not start any new one, returning a list of all waiting-to-execute jobs.
From JavaDocs :
The following method shuts down an ExecutorService in two phases,
first by calling shutdown to reject incoming tasks, and then calling
shutdownNow, if necessary, to cancel any lingering tasks:
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
You can always call future.get(timeout...)
It will return timeout exception if it did not finish yet... then you can call future.cancel().
As long as you deal with threads in Java the only safe way to stop the thread is to interrupt it. You can call shutdown() first and then wait. This method doesn't interrupt threads.
If it doesn't help then you call shutdownNow() which tries to cancel tasks by setting interrupted flag of each thread to true. In that case if threads are blocked/waiting then InterruptedException will be thrown. If you check interrupted flag somewhere inside your tasks then you are good too.
But if you have no other choice but to stop threads you still can do it. One possible solution of getting access to workers is to trace all created threads inside ThreadPoolExecutor with help of custom thread factory.
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class TestThreadPoolEx {
static class CustomThreadFactory implements ThreadFactory {
private List<Thread> threads = new ArrayList<>();
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
threads.add(t);
return t;
}
public List<Thread> getThreads() {
return threads;
}
public void stopThreads() {
for(Thread t : threads) {
if(t.isAlive()) {
try {
t.stop();
} catch (Exception e) {
//NOP
}
}
}
}
}
public static void main(String[] args) throws InterruptedException {
CustomThreadFactory factory = new CustomThreadFactory();
ExecutorService ex = Executors.newFixedThreadPool(1, factory);
ex.submit(() -> {
while(true);
});
ex.shutdown();
ex.awaitTermination(5, TimeUnit.SECONDS);
ex.shutdownNow();
ex.awaitTermination(5, TimeUnit.SECONDS);
factory.stopThreads();
}
}
This is sure unsafe but should fit your requirements. In this case it's able to stop while(true) loop. Cancelling tasks won't be able to do that.

Java Thread never receiving notify

I've been trying to make a simple Java thread application, where one thread waits, and another wakes it up after 3 seconds. However, I can't seem to make it work and I just can't figure out why.
public class Deadlock extends Thread {
Object lock = new Object();
public static void main(String[] args) {
//WAITER THREAD
Deadlock waiter = new Deadlock() {
#Override
public void run() {
System.out.println("Waiter started");
synchronized(lock) {
try{
System.out.println("Waiter will wait for notify...");
lock.wait();
System.out.println("Woke up!");
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}//run()
};
//WAKER THREAD
Deadlock waker = new Deadlock() {
#Override
public void run() {
System.out.println("Waker started");
synchronized(lock) {
System.out.println("Waker sleeping for 3 seconds.");
try{
Thread.sleep(3000);
}catch(InterruptedException e) {}
System.out.println("Waker notifying...");
lock.notifyAll();
}
}//run
};
waiter.start();
waker.start();
}
}
The output I get is:
Waiter started
Waiter will wait for notify...
Waker started
Waker sleeping for 3 seconds.
Waker notifying...
...and keeps running forever. I expected the waiter thread to wake up and the program to terminate.
Thanks
Your main problem is that the 'lock' is a class instance property so the two Deadlock instances do not share the same 'lock'. Hence, calling notifyAll() in the waker has no effect on the waiter because it's waiting on a different object. The simplest solution is to make 'lock' static:
static Object lock = new Object();
... I'd also make it private and final for good measure.
The second issue is that by starting the two threads together you don't really guarantee that the waiter will run first - I'd add a short delay before starting the waker.

Semaphores in Java. Why second thread is not waiting?

I have one static Semaphore instance.
Semaphore semaphore = new Semaphore(1);
Now I have two Threads (Sending Thread and Receiving Thread)
Sending Thread:
public class SendingThread implements Runnable {
private Semaphore semaphore;
public SendingThread(Semaphore semaphore){
this.semaphore = semaphore;
}
#Override
public void run() {
try {
System.out.println("1");
Thread.sleep(4000);
this.semaphore.acquire();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
}
and receiving Thread:
public class RecievingThread implements Runnable {
private Semaphore semaphore;
public RecievingThread(Semaphore semaphore){
this.semaphore = semaphore;
}
#Override
public void run() {
System.out.println("2");
this.semaphore.release();
System.out.println("3");
}
}
When I start this 2 threads according to my understanding Receiving Thread will wait for 4 second till
Sending Thread will notify it that Receiving Thread can continue. It means that System.out.println("3"); will be printed with 4 second delay, but when I run this code all three values are printed immediately. Why?
Am i missing something?
A new Semaphore(1) has 1 initial permit and thus allows for one immediate acquire to go through. Furthermore since a release is always allowed both threads proceeds immediately.
To force one thing to happen before the other, you can use new Semaphore(0). This will force the thread calling acquire to wait for the thread executing release.

Categories

Resources