I took your code, filled in the missing bits, fixed the compilation errors and ran it. It prints "TEST!!" lots of times. If I reduce the number of tasks to a reasonable number, it runs to completion. If I leave it at 10,000 the test fails with an OOME saying that it can't allocate any more thread stacks.
I want to have 10000 threads with waiting callables
My testing suggests that that many threads is going to cause you to run out of memory. It is really, really not a good idea.
Here is the exact code I used:
package test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorTest {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for (int i = 0; i < 10000; i++) {
exec.submit(new MyCallable());
}
}
}
package test;
import java.util.concurrent.Callable;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
class MyCallable implements Callable<String> {
private ReentrantLock lock = new ReentrantLock();
private Condition cond = lock.newCondition();
public String call() {
System.out.println("TEST!!");
try {
lock.lock();
cond.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return "foo";
}
}
Here's the while(true) {await}
test:
[steve@newbox ~]$ cat ./workspace/test/src/test/CondAwait.java
package test;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class CondAwait {
public static void main(String[] args) throws InterruptedException {
ReentrantLock lock = new ReentrantLock();
Condition cond = lock.newCondition();
lock.lock();
while(true){
System.out.println("Hi!");
cond.await();
}
}
}
[steve@newbox ~]$ java -cp ./workspace/test/bin test.CondAwait
Hi!
^C[steve@newbox ~]$
In short, the main thread freezes in the first await
call ... as I would have expected.
I agree that it`s not a good idea, but those threads will be like a request cache, user sends a request, it's processor should be put into the thread pool, if we have 10k requests per second, you will see 10k threads in the pool. Please suggest how to do it better.
Use a bounded thread pool, and set the bound to be roughly equal to the number of cores that you have.
Sure, you won't have your 10,000 callables all suspended at the same time, but that is a GOOD THING.
If these callables are meant to simulate requests that wait a few seconds for a something external to respond, then a thread pool of up to 100 might be reasonable. But if you really, really need massive parallelism then you should be looking at something that uses NIO selectors so that a small number of worker threads can run a large number of requests, interleaving them rather than blocking in I/O.