I would like to execute different tasks for each player in an event executor, but make sure that the tasks submitted for each player are in order. Here is a picture to hopefully explain in better.
Extra Information:
I know which player will be effected for each task
I receive the tasks for each player in a pseudo-random order. (I will not know the order of task input before hand)
I need each player to basically have their own "thread" so that their tasks execute in order of insertion.
What I have tried:
Currently I am using Executors.newSingleThreadExecutor() inside of each player object to mimic this functionality, but I don't think this will scale well with a lot of players. Hence why I am asking here to find a better method.
I see three main ways of achieving this.
Thread per player
This is a bit like what you are doing. Create a thread per player, dispatch work units to it; this is serial by nature.
It may not scale well to a few hundreds / thousands of players (a few hundred active threads usually do not scare mordern hardware - although it may not be really efficient).
But the readability and ligthness of the code will probably be unmatched by other solutions.
Shared threads with consistent routing
If a thread per player is not possible, then we will have to share threads, and a thread will deal with several players.
The key will be to have a given thread handle every task for a given player, so as to achieve serial execution.
Three ways of building this come to mind...
Create groups of players
If your players have something to allow for grouping (e.g. a Team, or even just a creation date)... then regroup your players by group, and implement a "Thread per group" pattern.
The only key issue is to have groups of roughly the same size, so as to share the load evenly.
Another issue, that you will have in almost every solution, will be to shutdown the thread for the group (how do you know when everything you wanted to process is finished ?).
Shared threads and ExecutorService
This is the "do it yourself way". The gist of it is
create a fixedThreadPool, say with 4 threads.
Create a 4 BlockingQueue that will hold every work units
Create 4 PlayerWorker instances and send them to the thread pool to being execution, one for each of the above BlockingQueue. The implementation of these workers is to pull data from one of the queues and execute it.
Dispatch your player work units by sending them to the queue. The key here is to always reuse the same queue for the same player (e.g. if your player has an identifier property, say a long, then dispatch all work units to the Math.abs(id % 4)th queue
Shut down the PlayerWorker and thread pool when everything is done
This is a lot of work, so...
Using a framework
Some people have already done it for you. The actor pattern is a very good fit for this problem. You should probably check out Akka and what is called ConsistentHashingRoutingLogic, which is a pretty much one to one mapping, conceptually at least, to what I just described.
The reactive way
If we step back a bit, we do not actually care about threads. We care about serial execution.
So we just need a way to perform some work after some other work is done. It should be just a call back !
And we have CompletableFuture for that (not to mention frameworks).
So why not create one CompletableFuture per player, and each time a new work unit is to be done for this player, use CompletableFuture.thenApply or thenApplyAsync.
By dispatching the executions to an appropriately sized execution pool, and letting the framework do the job, the tasks will be serially executed one after the other.
You can just create a singleEventExecutorService for each player.
class PlayerEventHandler {
private Map<Player, ExecutorService> executors = new ConcurrentHashMap<>();
public void handleEvent(PlayerEvent e) {
ExecutorService executor = executors.computeIfAbsent(e.getPlayer(), Executors.newSingleThreadExecutor());
executor.submit(e.execute());
}
}
Although this would probably behave much worse for 600 players than a single thread executor. However, you can probably group the players in some way so that a reasonable amount of players share an executor.
class PlayerEventHandler {
private Map<PlayerGroup, ExecutorService> executors = new ConcurrentHashMap<>();
public void handleEvent(PlayerEvent e) {
PlayerGroup group = determineGroup(e.getPlayer());
ExecutorService executor = executors.computeIfAbsent(group, Executors.newSingleThreadExecutor());
executor.submit(e.execute());
}
}
This will probably become a problem if the players change dynamically during runtime, because then you can end up with a single thread handling a lot of players, while another group has become empty over time.
It really depends on your actual case.
Related
i have multiple threads, who all run from one object.
i want the "main thread" to run alone until a certain point, then it waits and all the other threads run together, then the main thread wakes, etc.....
i am having trouble synchronizing my threads. i either get an Illegal Monitor State Exception, or it gets stuck in one of the "wait" loops that are suppose to receive a "notify" that never arrives.
more specifically, i have an object with an array. each cell in the array has a thread that checks the adjacent cells and then changes it's cell with that information.
in order to make the changes orderly, i want all the cells to first make the check of their adjacent cells and keep the value they produced, then wait.
when all of them are done, the main thread will wake all of them up and they will update their respective cells.
i looked up how "wait" and "notify" work, but i still don't understand how they sync. from what i understand i need to connect them all to one object, and then that object is the "lock", so if i use "synchronize" on its methods only one thread can approach it at a time? how can i make sure a "wait" method will always have a "notify" to end it?
Edit:
the method basically runs Conway's game of life.
the main orientation of the code is like so:
the class LifeMatrix extends JPanel. it had an array of panels, each is either "dead or alive" (true/false). the class RunMatrixThread extends thread, and is the "main thread" that coordinates the code. the class CellThead extends thread, and a CellThread is made for every cell in the matrix.
so my idea was to give all the threads the "LifeMatrix" as an observer, but if i try to notify the LifeMatrix Object (with matrix.notify()) it gives me the Illigal Monitor State Exception, and if i try to use "notify all" it gets stuck in RunMatrixThread's wait() command.
also, do i notify an object? or do i notify the threads that are waiting?
Don't use parallelization. Before using threads think if you really can parallelize your job because if all of your tasks have to be sync with each other use threads won't give you better perfomance in terms of execution time. Say that you have an array of objects [a,b] if a must waiting for some changes on b, you can't treat a and b separately so you can't parallelize your job. On the contrary if you need to process a, b and all the elements of your array and at the end perform some computation on them you can Join the threads with join() method. When you call join method you basically join threads branches in one (the main thread). A new thread will fork your main thread and join will join these threads.
If you're trying to get "worker threads" to do parcels of work that are authorized/initiated/doled-out by a "main" thread, then you probably should be using a thread pool (e.g, https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html)
A thread pool takes care of creating the worker threads and "synchronizing" their activity with the main thread, and it lets you focus on the task (or tasks) that the workers perform.
each cell in the array has a thread that...
For Conway's Life, that's way too many worker threads. If the work is purely compute-bound, then there's no point in having many more threads than your host has processors to execute them.
If I was coding life for a host with N processors, I would use a thread pool that had N threads. And, In each generation, I would have the main thread submit N tasks to the pool: Each task would do one horizontal stripe of the board.
Ok, first of all i want to thank all of you for trying to help, some of the links you gave me were very helpful.
I found out what my problem was: i was trying to use wait/notify methods from 2 different types of threads at the same time, on the same object. i had the 'CellThread' that used wait and 'notifyAll', and i had the 'RunMatrixThread' that did the same. they of course had "synchronized" methods, but because they were 2 different TYPES of threads, the two types weren't in sync with EACH OTHER.
what solved the problem was that i made 2 new synchronized methods within the 'RunMatrixThread' class, one for waiting and one for notifying, and then just called those methods from all threads (from both thread classes) whenever i wanted to wait/notify. in this way, there was a unified object that had a lock on everything.
PS: i know its a bad idea to use so many threads. it was the coarse's assignment, and they required we do it this way.
and excuse the lack of knowledge on multithreaded apps, but I am new to the field.
Is there a pattern or common used methodology for monitoring the 'job completion' or 'job status' of worker threads from a monitor (a class that acts as a monitor)?
What I have currently done is create a list of workers and create one thread for each worker. After all threads have started i am looping over the worker list and 'checking their status' by making a call to a method.
At that time I couldn't come up with a different solution, but being new to the field, I don't know if this is the way to go, or if there are other solutions or patterns that I should study.
Depending on what you want, there are many ways that you can do this.
If you just want to wait until all the threads finish (i.e. all you care about is having everything finish before moving on), you can use Thread.join():
try {
for (Thread t: threadsIWaitOn)
t.join();
} catch (InterruptedException iex) {
/* ... handle error ...
}
If you want a more fine-grained control over the thread status and want to be able, at any time, to know what threads are doing, you can use the Thread.getState() function. This returns a Thread.State object that describes whether the thread is running, blocked, new, etc., and the Javadoc specifically says that it's designed for monitoring the state of a thread rather than trying to synchronize on it. This might be want you want to do.
If you want even more information than that - say, how to get a progress indicator for each thread that counts up from 0 to 100 as the thread progresses - then another option might be to create a Map from Threads to AtomicIntegers associating each thread with a counter, then pass the AtomicInteger into the constructor of each thread. That way, each thread can continuously increment the counters, and you can have another thread that continuously polls the progress.
In short, you have a lot of options based on what it is that you're trying to accomplish. Hopefully something in here helps out!
Use a ThreadPool and Executor, then you get a Future<> and you can poll for their completion and some more nice stuff, too. I can appreciate this book for you: Java Concurrency in Practice
Try to use any kind of synchronization. For example, wait on some kind of monitor/semaphore until job is done / whatever you need.
I am a newbie to Java concurrency and am a bit confused by several concepts and implementation issues here. Hope you guys can help.
Say, I have a list of tasks stored in a thread-safe list wrapper:
ListWrapper jobs = ....
'ListWrapper' has synchronized fetch/push/append functions, and this 'jobs' object will be shared by multiple worker threads.
And I have a worker 'Runnable' to execute the tasks:
public class Worker implements Runnable{
private ListWrapper jobs;
public Worker(ListWrapper l){
this.jobs=l;
}
public void run(){
while(! jobs.isEmpty()){
//fetch an item from jobs and do sth...
}
}
}
Now in the main function I execute the tasks:
int NTHREADS =10;
ExecutorService service= Executors.newFixedThreadPool(NTHREADS);
//run threads..
int x=3;
for(int i=0; i<x; i++){
service.execute(new Worker(jobs) );
}
I tested this code with 'x=3', and I found that only 3 threads are running at the same time; but as I set 'x=20', I found that only 10 (=NTHREADS) are running at the same time. Seems to me the # of actual threads is the min of the two values.
Now my questions are:
1) Which value ('x' or 'NTHREADS') should I set to control the number of concurrent threads? Or it doesn't matter in either I choose?
2) How is this approach different from simply using the Producer-Consumer pattern --creating a fixed number of 'stud' threads to execute the tasks(shown in the code below)?
Thread t1= new Worker(jobs);
Thread t2= new Worker(jobs);
...
t1.join();
t2.join();
...
Thank you very much!!
[[ There are some good answers here but I thought I'd add some more detail. ]]
I tested this code with 'x=3', and I found that only 3 threads are running at the same time; but as I set 'x=20', I found that only 10 (=NTHREADS) are running at the same time. Seems to me the # of actual threads is the min of the two values.
No, not really. I suspect that the reason you weren't seeing 20 threads is that threads had already finished or had yet to be started. If you call new Thread(...).start() 20 times then you will get 20 threads started. However, if you check immediately none of them may have actually begun to run or if you check later they may have finished.
1) Which value ('x' or 'NTHREADS') should I set to control the number of concurrent threads? Or it doesn't matter in either I choose?
Quoting the Javadocs of Executors.newFixedThreadPool(...):
Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue. At any point, at most nThreads threads will be active processing tasks.
So changing the NTHREADS constant changes the number of threads running in the pool. Changing x changes the number of jobs that are executed by those threads. You could have 2 threads in the pool and submit 1000 jobs or you could have 1000 threads and only submit 1 job for them to work on.
Btw, after you have submitted all of your jobs, you should then shutdown the pool which stops all of the threads if all of the jobs have been run.
service.shutdown();
2) How is this approach different from simply using the Producer-Consumer pattern --creating a fixed number of 'stud' threads to execute the tasks(shown in the code below)?
It differs in that it does all of the heavy work for you.
You don't have to create a ListWrapper of the jobs since you get one inside of the ExecutorService. You just submit the jobs to the ExecutorService and it keeps track of them until the threads are available to run them.
You don't have to create any threads or worry about them throwing exceptions and dying because the ExecutorService starts/restarts the threads for you.
If you want your tasks to return information you can make use of the submit(Callable) method and use the Future to get the results of the jobs. Etc, etc..
Doing this code yourself is going to be harder to get right, more code to maintain, and most likely will not perform as well as the code in the JDK that is battle tested and optimized.
You shouldn't create threads by yourself when using a threadpool. Instead of WorkerThread class you should use a class that implements Runnable but is not a thread. Passing a Thread object to the threadpool won't make the thread run actually. The object will be passed to a different internal thread, which will simply execute the run method of your WorkerThread class.
The ExecutorService is simply incompatible with the way you want to write your program.
In the code you have right now, these WorkerThreads will stop to work when your ListWrapper is empty. If you then add something to the list, nothing will happen. This is definitely not what you wanted.
You should get rid of ListWrapper and simply put your tasks directly into the threadpool. The threadpool already incorporates an internal list of jobs shared between the threads. You should just submit your jobs to the threadpool and it will handle them accordingly.
To answer your questions:
1) Which value ('x' or 'NTHREADS') should I set to control the number of concurrent threads? Or it doesn't matter in either I choose?
NTHREADS, the threadpool will create the necessary number of threads.
2) How is this approach different from simply using the Producer-Consumer pattern --creating a fixed number of 'stud' threads to execute the tasks(shown in the code below)?
It's just that ExecutorService automates a lot of things for you. You can choose from a lot of different implementations of threadpools and you can substitute them easily. You can use for instance a scheduled executor. You get extra functionality. Why reinvent the wheel?
For 1) NTHREADS is the maximum threads that the pool will ever run concurrently, but that doesn't mean there will always be that many running. It will only use as many as is needed up to that max value... which in your case is 3.
As the docs say:
At any point, at most nThreads threads will be active processing tasks. If additional tasks are submitted when all threads are active, they will wait in the queue until a thread is available
http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool-int-
As for 2) using Java's concurrent executors framework is preferred with new code. You get a lot of stuff for free and removes the need for having to handle all of the fiddly thread work yourself.
The number of threads passed into newFixedThreadPool is at most how many threads could be running executing your tasks. If you only have three tasks ever submitted I'd expect the ExecutorService to only create three threads.
To answer your questions:
You should use the number you pass into the constructor to control how many threads are going to be used to execute your tasks.
This differs because of the extra functionality the ExecutorService gives you, as well as the flexibility it gives you such as in the case you need to change your ExecutorService type or number of tasks you'll run (less lines of code to change).
All that is happening is the executor service is only creating as many threads as it needs. NTHREADS is effectively the maximum number of threads it'll create.
There is no point creating ten threads up front if it only has 3 tasks to complete, the other 7 will just be hanging around consuming resources.
If you submit more than NTHREADS number of tasks then it will process that number concurrently and the rest will wait on a queue until a thread becomes free.
This isn't any different from creating a fixed set of your own threads, except the thread management and scheduling is handled for you. The executor service also restarts threads if they are killed by rogue exceptions in your task which you'd otherwise have to code for.
See: The Javadoc on Executorservice.newFixedThreadPool
I suspect this is really easy but I’m unsure if there’s a naïve way of doing it in Java. Here’s my problem, I have two scripts for processing data and both have the same inputs/outputs except one is written for the single CPU and the other is for GPUs. The work comes from a queue server and I’m trying to write a program that sends the data to either the CPU or GPU script depending on which one is free.
I do not understand how to do this.
I know with executorservice I can specify how many threads I want to keep running but not sure how to balance between two different ones. I have 2 GPU’s and 8 CPU cores on the system and thought I could have threadexecutorservice keep 2 GPU and 8 CPU processes running but unsure how to balance between them since the GPU will be done a lot quicker than the CPU tasks.
Any suggestions on how to approach this? Should I create two queues and keep pooling them to see which one is less busy? or is there a way to just put all the work units(all the same) into one queue and have the GPU or CPU process take from the same queue as they are free?
UPDATE: just to clarify. the CPU/GPU programs are outside the scope of the program I'm making, they are simply scripts that I call via two different method. I guess the simplified version of what I'm asking is if two methods can take work from the same queue?
Can two methods take work from the same queue?
Yes, but you should use a BlockingQueue to save yourself some synchronization heartache.
Basically, one option would be to have a producer which places tasks into the queue via BlockingQueue.offer. Then design your CPU/GPU threads to call BlockingQueue.take and perform work on whatever they receive.
For example:
main (...) {
BlockingQueue<Task> queue = new LinkedBlockingQueue<>();
for (int i=0;i<CPUs;i++) {
new CPUThread(queue).start();
}
for (int i=0;i<GPUs;i++) {
new GPUThread(queue).start();
}
for (/*all data*/) {
queue.offer(task);
}
}
class CPUThread {
public void run() {
while(/*some condition*/) {
Task task = queue.take();
//do task work
}
}
}
//etc...
Obviously there is more than one way to do it, usually simplest is the best. I would suggest threadpools, one with 2 threads for CPU tasks, second with 8 threads will run GPU tasks. Your work unit manager can submit work to the pool that has idle threads at the moment (I would recommend synchronizing that block of code). Standard Java ThreadPoolExecutor has getActiveCount() method you can use for it, see
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html#getActiveCount().
Use Runnables like this:
CPUGPURunnable implements Runnable {
run() {
if ( Thread.currentThread() instance of CPUGPUThread) {
CPUGPUThread t = Thread.currentThread();
if ( t.isGPU())
runGPU();
else
runCPU();
}
}
}
CPUGPUThreads is a Thread subclass that knows if it runs in CPU or GPU mode, using a flag. Have a ThreadFactory for ThreadPoolExecutors that creates either a CPU of GPU thread. Set up a ThreadPoolExecutor with two workers. Make sure the Threadfactory creates a CPU and then a GPU thread instance.
I suppose you have two objects that represents two GPUs, with methods like boolean isFree() and void execute(Runnable). Then you should start 8 threads which in a loop take next job from the queue, put it in a free GPU, if any, otherwise execute the job itself.
Assume that I have a set of objects that need to be analyzed in two different ways, both of which take relatively long time and involve IO-calls, I am trying to figure out how/if I could go about optimizing this part of my software, especially utilizing the multiple processors (the machine i am sitting on for ex is a 8-core i7 which almost never goes above 10% load during execution).
I am quite new to parallel-programming or multi-threading (not sure what the right term is), so I have read some of the prior questions, particularly paying attention to highly voted and informative answers. I am also in the process of going through the Oracle/Sun tutorial on concurrency.
Here's what I thought out so far;
A thread-safe collection holds the objects to be analyzed
As soon as there are objects in the collection (they come a couple at a time from a series of queries), a thread per object is started
Each specific thread takes care of the initial pre-analysis preparations; and then calls on the analyses.
The two analyses are implemented as Runnables/Callables, and thus called on by the thread when necessary.
And my questions are:
Is this a reasonable scheme, if not, how would you go about doing this?
In order to make sure things don't get out of hand, should I implement a ThreadManager or some thing of that sort, which starts and stops threads, and re-distributes them when they are complete? For example, if i have 256 objects to be analyzed, and 16 threads in total, the ThreadManager assigns the first finished thread to the 17th object to be analyzed etc.
Is there a dramatic difference between Runnable/Callable other than the fact that Callable can return a result? Otherwise should I try to implement my own interface, in that case why?
Thanks,
You could use a BlockingQueue implementation to hold your objects and spawn your threads from there. This interface is based on the producer-consumer principle. The put() method will block if your queue is full until there is some more space and the take() method will block if the queue is empty until there are some objects again in the queue.
An ExecutorService can help you manage your pool of threads.
If you are awaiting a result from your spawned threads then Callable interface is a good idea to use since you can start the computation earlier and work in your code assuming the results in Future-s. As far as the differencies with the Runnable interface, from the Callable javadoc:
The Callable interface is similar to Runnable, in that both are designed for classes whose instances are potentially executed by another thread. A Runnable, however, does not return a result and cannot throw a checked exception.
Some general things you need to consider in your quest for java concurrency:
Visibility is not coming by defacto. volatile, AtomicReference and other objects in the java.util.concurrent.atomic package are your friends.
You need to carefully ensure atomicity of compound actions using synchronization and locks.
Your idea is basically sound. However, rather than creating threads directly, or indirectly through some kind of ThreadManager of your own design, use an Executor from Java's concurrency package. It does everything you need, and other people have already taken the time to write and debug it. An executor manages a queue of tasks, so you don't need to worry about providing the threadsafe queue yourself either.
There's no difference between Callable and Runnable except that the former returns a value. Executors will handle both, and ready them the same.
It's not clear to me whether you're planning to make the preparation step a separate task to the analyses, or fold it into one of them, with that task spawning the other analysis task halfway through. I can't think of any reason to strongly prefer one to the other, but it's a choice you should think about.
The Executors provides factory methods for creating thread pools. Specifically Executors#newFixedThreadPool(int nThreads) creates a thread pool with a fixed size that utilizes an unbounded queue. Also if a thread terminates due to a failure then a new thread will be replaced in its place. So in your specific example of 256 tasks and 16 threads you would call
// create pool
ExecutorService threadPool = Executors.newFixedThreadPool(16);
// submit task.
Runnable task = new Runnable(){};;
threadPool.submit(task);
The important question is determining the proper number of threads for you thread pool. See if this helps Efficient Number of Threads
Sounds reasonable, but it's not as trivial to implement as it may seem.
Maybe you should check the jsr166y project.
That's probably the easiest solution to your problem.