A friend familiar with Java multithreading must know a lot about the thread pool of JAva, the core implementation class in the JDK is java.util.concurrent.ThreadPoolExecutor. You may be aware of its principle, even read its source code; But like me, people may misunderstand its role ... Now the question is, why does the JDK provide the Java thread pool? What are the advantages of using the Java thread pool for creating a new thread every time?
misunderstanding of the thread pool
For a long time I always thought the Java thread pool was designed to improve the efficiency of creating threads under multithreading. Create some threads and cache the online pool, followed by a request (Runnable) to fetch a thread from the connection pool to process the request, thus avoiding the creation of a new thread object at a time. Until a while ago I saw an article by Neal Gafter (and Joshua Bloch co-authored "Java Puzzlers", now working in Microsoft, mainly engaged in. NET language work), in which there is such a conversation (Http://www.infoq.com/cn/articles/neal-gafter-on-java):
At first glance, the idea of a great God is different: Is the Java thread pool designed to prevent Java threads from consuming too much resources?
Although the great God of Java interview, but also can not believe everything, you say that the resources accounted for resources? Still have to write the test case to measure.
First of all, verify my understanding:
What is the high efficiency of the Java thread pool and the creation of Java threads?
Directly on the test case:
public class threadpooltest extends testcase { private static final int count = 10000; public void Testthreadpool () throws InterruptedException { Countdownlatch countdownlatch = new countdownlatch (COUNT); executorservice executorservice = executors.newfixedthreadpool (; ) long bg = system.currenttimemillis (); for (int i = 0; i < count; i++) { runnable command = new testrunnable (CountDownLatch); executorservice.execute (command); } countdownlatch.await (); system.out.println (" Testthreadpool: " + (System.currenttimemillis () - bg)); } public void testnewthread () throws InterruptedException { CountDownLatch countDownLatch = new Countdownlatch (COUNT); long bg = System.currenttimemillis (); for (int i = 0; i < count; i++) { runnable command = new testrunnable (Countdownlatch); thread thread = new thread ( command); thread.start (); } countdownlatch.await (); &Nbsp; system.out.println ("Testnewthread:" + ( System.currenttimemillis () &NBSP;-&NBSP;BG)); } private static class testrunnable implements runnable { private final CountDownLatch countDownLatch; testrunnable (Countdownlatch countdownlatch) { this.countdownlatch = countDownLatch; } @Override public void run () { countdownlatch.countdown (); } }}
The Executors.newfixedthreadpool (100) is used here to control the number of core connections in the thread pool as large as the maximum number of connections, both 100.
The test results on my machine:
testthreadpool:31testnewthread:624
As you can see, the processing time for processing 10,000 requests using the thread pool is 31ms, while the processing time for each new thread enabled is 624ms.
Well, using the thread pool is a bit faster than creating a new thread each time, but the Testnewthread takes a total of 624ms, and the average per-request time is:
624ms/10000=62.4us
The time to create and start a thread is 62.4 microseconds each time. According to the 80/20 principle, the craved time can be negligible at all. So the thread pool is not designed for efficiency.
is the Java thread pool designed to conserve resources?
re-test case:
public class threadpooltest extends testcase { public Void testthread () throws InterruptedException { int i = 1; while (True) { runnable command = new testrunnable (); thread thread = new thread (command); thread.start (); system.out.println (i++); } } private static class TestRunnable implements Runnable { @Override public void run () { try { Thread.Sleep (&NBSP;&NB);sp; } catch (interruptedexception e) { e.printstacktrace (); } } }}
The above use case simulates each request to create a new thread processing request, and then the default processing time for each request is 1000ms. And the memory overflows when the number of requests to my machine reaches 1096:
Java.lang.OutOfMemoryError:unable to create new native thread
Why do you throw an oom error? Because the JVM allocates a certain amount of memory for each thread (JDK5.0 after each thread stack size is 1M, the previous thread stack size is 256K, and can be set by the JVM parameter-XSS), the error is reported when the number of threads reaches a certain number.
Imagine that if you do not use the Java thread pool and create a new thread for each request to handle the request, it will be memory overrun when the amount of requests reaches a certain amount, and if we use the Java thread pool, the number of threads is bound to <=maximumpoolsize ( The maximum number of threads in the thread pool ), so a reasonable setting will not cause a memory overflow .
Now the problem is clear: the Java thread pool is designed to prevent memory overflow, not to speed up efficiency.
Talking about Java thread pool
As described above, the Java thread pool boot too much will cause OOM, and the Java thread pool should also set a reasonable number of threads, otherwise the application may be very unstable. But how do you set this quantity? We can use this formula to calculate:
(maxprocessmemory-jvmmemory-reservedosmemory)/(threadstacksize) = Max number of threads
Maxprocessmemory Process Max Memory
Jvmmemory JVM Memory
Reservedosmemory local memory of the JVM
Size of the Threadstacksize line stacks
maxprocessmemory
Maxprocessmemory: The maximum address space of a process, of course, cannot exceed the sum of virtual memory and physical memory. Refer to the table below for the maximum addressable space for processes in different systems:
Maximum Address Space Per Process |
|
Operating System |
Maximum Address Space Per Process |
redhat Linux + |
2 GB |
redhat Linux-bit |
3 GB |
windows 98/2000/nt/me/xp |
2 GB |
solaris x86 (+ bit) |
4 GB |
solaris-bit |
4 GB |
Solaris a bit |
Terabytes |
jvmmemory
Jvmmemory:heap + PermGen, that is, heap memory and permanent generation memory and (note, excluding local memory).
reservedosmemory
Reservedosmemory:native Heap, which is the memory occupied by the Jni invocation method.
threadstacksize
Threadstacksize: The size of the line stacks, JDK5.0 after each thread stack size defaults to 1M, the previous thread stack size is 256K, can be set by the JVM parameter-XSS, note that-XSS is a non-standard parameter of the JVM, does not force all platform JVM Support.
How to increase the number of threads?
If the program requires a large number of threads and the existing settings do not meet the requirements, you can increase the number of threads that can be created by modifying the maxprocessmemory,jvmmemory,threadstacksize three factors:
Maxprocessmemory using 64-bit operating systems
Jvmmemory Reduction of jvmmemory distribution
Threadstacksize reducing the stack size of a single thread
Talking about Java thread pool