How To Store Threads In A Multi-threaded Application
Solution 1:
Answer given by @Michael is fine but I would prefer to get this job done by using Java's executor service, because it gives more control, elegant way to do this and that's what Java provided API to deal with these kind of situations.
See below code example. Clear advantage of this approach is that you can control maximum number of threads running in your JVM, which is extremely important otherwise over period of time your application may start clocking, so this is gives more scalability to your application/solution.
If you are not aware of Java's executor service then below are few quick points to get you started:
- Java's utility class
Executors
will create and return objects ofExecutorService
(please note thatExecutorService
is an interface). - Now in case of
newCachedThreadPool()
,newFixedThreadPool(int nThreads)
you will get an object ofThreadPoolExecutor
(please note thatThreadPoolExecutor
implementsExecutorService
interface). - When you do
Executors.newFixedThreadPool(2);
, you only get an object ofThreadPoolExecutor
with all instance variables like core pool size, max pool size etc. set, and in your case it will be set to 2. - Now, with
private final static ExecutorService executorService = Executors.newFixedThreadPool(2);
you will always have max of 2 threads in your JVM for this thread pool, and any excess request will get queued up inLinkedBlockingQueue
implementation, and sinceLinkedBlockingQueue
is a unbounded queue so you will never loose your task. - Suppose you want to create more threads when you have more load then you have to play around with
maximumPoolSize
and use a bounded queue. So, depending on your system capacity / application load you can start withcorePoolSize
of let say 100 and setmaximumPoolSize
asInteger.MAX_VALUE
.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
publicclassExecutorServiceImplementationExample {
privatefinalstaticintMAX_NUMBER_OF_THREADS= Integer.MAX_VALUE;
// set maximum number of threads as per your requirement/performance tuning, for testing set it to "2" and to have better feel.privatefinalstaticExecutorServiceexecutorService= Executors.newFixedThreadPool(MAX_NUMBER_OF_THREADS);
publicstaticvoidmain(String[] args) {
System.out.println("### Starting.");
newThread(){
@Overridepublicvoidrun() {
scheduleTask(newMyRunnableTask());
}
}.start();
newThread(){
@Overridepublicvoidrun() {
scheduleTask(newMyRunnableTask());
}
}.start();
newThread(){
@Overridepublicvoidrun() {
scheduleTask(newMyRunnableTask());
}
}.start();
newThread(){
@Overridepublicvoidrun() {
scheduleTask(newMyRunnableTask());
}
}.start();
System.out.println("### Completed.");
}
privatestaticvoidscheduleTask(Runnable runnable) {
executorService.execute(runnable);
}
}
MyRunnableTask.java
publicclassMyRunnableTaskimplementsRunnable {
@Overridepublicvoidrun() {
System.out.println("I am getting executed: " + this.hashCode() + " | " + Thread.currentThread().getId());
try {
Thread.sleep(2000); // this sleep is only for testing to give a feel of how solution will work, remove after testing.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
In your case you will do something like below, and you need to have executorService
created in the start and your Game
class should implement Runnable
interface.
publicvoidonTweet() {
executorService.execute(new Game());
}
Solution 2:
I would create a map of users to the thread which their game is taking place on.
privateMap<String, Thread> games = newHashMap<>();
publicvoidonTweet(String user) {
if (!games.containsKey(user)) // if they haven't got a game running
{
Thread t = newThread(newGame());
t.start();
games.put(user, t);
}
}
publicvoidonStop(String user) {
if (games.containsKey(user))
{
games.remove(user).interrupt();
}
else
{
//should we handle this?
}
}
You will need to ensure the thread is prepared to deal with interrupts.
Post a Comment for "How To Store Threads In A Multi-threaded Application"