Thread group and thread pool one. Thread Group 1. Introduction and use of thread groups
Java uses Threadgroup to represent thread groups, which can classify a batch of threads, and Java allows direct control of thread groups. Control over thread groups is equivalent to controlling this batch of threads.
By default, the child thread and the parent thread that created it belong to a thread group.
Once a thread is a group of threads, that thread will always belong to that thread group, knowing that the thread is dead and the thread's group that it belongs to cannot be changed while it is running.
Thread provides different constructors to set which thread group the newly created thread belongs to. The Getthreadgroup () method is provided to return the thread group object to which the thread belongs.
The Threadgroup class provides the following two constructors to create an instance.
- Threadgroup (String name): Creates a new thread group with the specified thread group name
- Threadgroup (threadgroup parent,string name): Creates a new thread group with the specified name, specified parent thread group
The Java program does not allow the thread group name to be fetched by the GetName () method.
The Threadgroup class provides the following common methods
- int Activecount (): Returns the number of active threads in this thread group
- Interrupt (): Interrupts all threads in this thread group
- Isdaemon (): Determines whether the thread group is a background thread group
- Setdaemon (Boolean daemon): Sets the thread group as a background thread group.
- setmaxpriority (int pri): Sets the highest priority of the thread group.
2. Thread groups and exception handling mechanisms
Starting with Java 5, Java enforces thread exception handling if an unhandled exception is thrown during thread execution. The JVM will automatically look for a corresponding Thread.uncaughtexceptionhandler object before ending the thread, and if it finds the processor object, it will call the uncaughtexception of the object (thread t,throwable e) method to handle the exception.
The thread class provides two methods for setting an exception handler.
- Static Setdefaultuncaughtexceptionhandler (Thread.uncaughtexceptionhandler EH): Sets the default exception handler for all thread instances of the thread class
- Setuncaughtexceptionhandler (Thread.uncaughtexceptionhandler EH): Sets the exception handler for the specified thread instance
The Threadgroup class implements the Thread.uncaughtexceptionhandler interface, so the thread group that each thread belongs to will be the default exception handler.
If an unhandled exception is thrown during thread execution, The JVM will automatically look for a corresponding Thread.uncaughtexceptionhandler object before ending the thread, and if it finds the processor object, it will call the uncaughtexception of the object (thread t,throwable e) method to handle the exception, otherwise the JVM calls the Uncaughtexception () method of the thread group object that the thread belongs to to handle the exception.
The process for thread group handling exceptions is as follows:
- If the thread group has a parent thread group, the Uncaughtexception () method of the parent thread group is called to handle the exception.
- If the thread class that the thread instance belongs to has a default exception handler, call the exception handler to handle the exception
- If the object is a Threaddeath object, no processing is done; otherwise, the information for the exception trace stack is printed to the SYSTEM.ERR error output stream and ends the thread.
The following main program sets the exception handler.
PackageCom.gdut.thread;classMyexhandlerImplementsthread.uncaughtexceptionhandler{@Override Public voiduncaughtexception (Thread T, Throwable e) {System.out.println (t+ "Thread has an exception" +e); }} Public classExhandler { Public Static voidMain (string[] args) {thread.currentthread (). Setuncaughtexceptionhandler (NewMyexhandler ()); inta=5/0; System.out.println ("Program ends normally"); }}
Output: Thread[main,5,main] Thread unexpected java.lang.ArithmeticException:/by zero
Two. Thread pool
The cost of the system to start a new thread is very high because it involves interacting with the operating system. When you need to create a lot of short-lived threads in your program, you should consider using a thread pool to improve system performance.
Similar to the database connection pool, the thread pool creates a large number of idle threads when the system starts, and when the order brings a Runnable object or callable object to the thread pool, the thread pool will initiate one of the threads to execute their run () or call () method when run () or call () At the end of the method execution, the thread does not die, but returns again to the run () or call () method of the thread pool called idle, waiting to execute the next Runnable object.
In addition, the use of thread pool can effectively control the number of concurrent threads in the system, when the system contains a large number of concurrent threads, can cause severe degradation of system performance, and even cause the JVM to crash.
2.1 Java 8 Improved thread pool 2.2 Java 8 Enhanced line pooling
In order to take advantage of the advantages of multi-CPU, multi-core CPU performance advantage. You can test multiple small tasks, put small tasks in parallel execution on multiple processor cores, and when multiple small tasks are completed, merge the results together. Java 7 provides forkjoinpool to support this feature.
Forkjoinpool is an implementation class for Executorservice and is therefore a special thread pool. The following two commonly used constructors are available
- Forkjoinpool (int parallelism): Creates a forkjoinpool that contains parallelism parallel threads.
- Forkjoinpool (): Creates Forkjoinpool with the return value of the Runtime.availableprossesors () method as the Paralelism parameter.
Java 8 Further expands the functionality of the Forkjoinpool, and Java 8 adds common pool functionality. Forkjoinpool provides common pool functionality through the following two methods.
- Forkjoinpool Commonpool (): This method returns a common pool where the state of the universal pool is not affected by the shutdown () or Shutdownnow () method.
- int getcommonpoolparallelism (): This method returns the parallel level of the common pool.
Once you have created a common pool Forkjoinpool instance, you can call Forkjoinpool's submit (Forkjointask Task) or invoke (Forkjointask Task) method to perform the specified task. Where Forkjointask represents a parallel, consolidated task.
Forkjointask is an abstract class, and it has two abstract subclasses: Recursiveaction and Recursivetask. where recursiveaction represents a task that does not return a value, Recursivetask represents a task with a return value.
The following program divides the values of a large task (print 0~500) into small tasks and gives the task to Forkjoinpool to execute.
PackageCom.gdut.thread.threadPool;ImportJava.util.concurrent.ForkJoinPool;Importjava.util.concurrent.RecursiveAction;ImportJava.util.concurrent.TimeUnit;classPrinttaskextendsrecursiveaction{Private Static Final intTHRESHOLD = 50; Private intstart; Private intend; PublicPrinttask (intStartintend) { This. Start =start; This. end =end; } @Overrideprotected voidCompute () {if(end-start<THRESHOLD) { for(inti = start; I <end; i++) {System.out.println (Thread.CurrentThread (). GetName ()+ "I value" +i); } }Else{ //when the difference between end and start is greater than threshold, that is, to print more than 50 o'clock, divide the large task into two small tasks intMiddle = (End+start)/2; Printtask Left=NewPrinttask (Start,middle); Printtask Right=NewPrinttask (middle,end); Left.fork (); Right.fork (); } }} Public classforkjoinpooltest{ Public Static voidMain (string[] args)throwsinterruptedexception{Forkjoinpool Pool=NewForkjoinpool (); Pool.submit (NewPrinttask (0,500)); Pool.awaittermination (2, Timeunit.seconds); Pool.shutdown (); }}
8-core computer execution effect
Multithreading three (thread group and thread pool)