Hello,

I encountered a problem in a program I am writing. I thought to make a new simple one that has the exact situation and try to solve it.

I wanted first to try and solve it myself using my knowledge and then present it here to you. So, I got a solution.

I want to start a method. It creates and run a few threads. I want my method to pause after creating the threads and when they are done, continue it.

So, I created an Animation Class that implements the Runnable interface. I created another class named ThreadsList which extends the ArrayList class. So each time an Animation thread is created, it adds its object to the list. When it finished running, it removes the object from that list and checks if the ThreadList is empty. If it is not, it does nothing. When the last Thread removes itself, it should send a signal to the method to indicate that all Threads are done and that it can continue.

Thus, I used Semaphore in my method. I create the Threads and put the semaphore to acquire a permit. So when the ThreadsList is empty, it releases a permit and the main method continues.

I am putting you the code I used.

Java Code:
import java.util.concurrent.Semaphore;


public class Controller {

	private Semaphore semaphore = new Semaphore(0);
	private AnimationList animationList = new AnimationList(semaphore);


	public Controller() throws InterruptedException {

		System.out.println("Started");

		new Animation("a", animationList).start();
		new Animation("b", animationList).start();
		new Animation("c", animationList).start();
		new Animation("d", animationList).start();
		new Animation("e", animationList).start();
		new Animation("f", animationList).start();
		new Animation("g", animationList).start();

		pause();

		System.out.println("Ended");


	}

	private void pause() throws InterruptedException {
		semaphore.acquire();
	}


	public static void main(String[] args) throws InterruptedException {
		new Controller();
	}

}
Java Code:
import java.util.Random;


public class Animation extends Thread {

	private String text;
	private Random random = new Random();
	private int interval = random.nextInt(1501);
	private AnimationList threadsList;

	public Animation(String text, AnimationList threadsList) {
		this.text = text;
		this.threadsList = threadsList;

		System.out.println("Starting Thread : " + text);
	}

	public void run() {try {runThread();} catch (InterruptedException e) {}}

	public void runThread() throws InterruptedException {

		threadsList.add(this);

		Thread.sleep(interval);
		System.out.println(this.text + "1");
		Thread.sleep(interval);
		System.out.println(this.text + "2");
		Thread.sleep(interval);
		System.out.println(this.text + "3");

		threadsList.removeAnimationAndCheckIfEnded(this);
	}

}
Java Code:
import java.util.ArrayList;
import java.util.concurrent.Semaphore;


public class AnimationList extends ArrayList<Animation> {

	private static final long serialVersionUID = 1L;

	private Semaphore semaphore;

	public AnimationList(Semaphore semaphore) {

		this.semaphore = semaphore;

	}

	public synchronized void removeAnimationAndCheckIfEnded(Animation animation) {

		ArrayList<Animation> animationListTemp = new ArrayList<>(this);

		for(Animation animationTemp : animationListTemp)
			if(animationTemp.equals(animation))
				this.remove(animation);

		System.out.println("threads still running " + this.size());

		if(this.isEmpty())
			semaphore.release();

	}

}
By all means, introduce me a better way to handle the situation.

Thank you.