Thread groups
The relationship between threads and thread groups is similar to the relationship between files and folders; A Thread group can contain multiple threads and other Thread groups. The Thread class has several constructors that allow us to specify the Thread group that the Thread belongs to when it is created. If not, the Thread belongs to its parent Thread group
The Java virtual machine assigns a thread group to the main thread when it is created. Therefore, any Thread in the Java platform has a Thread group associated with it, which can be obtained through the thread.getThreadGroup () call
The use of ThreadGroup was abandoned in practice due to design flaws; There are alternatives
Store the thread in an array or collection object, but be aware of memory leaks
B, using thread name naming rules to achieve
Reliability: uncaught exceptions and monitoring of threads
If a thread’s run method throws an uncaught exception, the thread terminates prematurely as the run method exits. Void uncaughtException(Thread t, Throwable E); void UncaughtExceptionHandler (Thread t, Throwable E); T: the terminated thread itself, the exception that causes the thread to terminate;
How do you set up the thread that catches the exception?
Before we start the thread by invoking thread. SetUncaughtExceptionHandler (new UncaughtExceptionHander ()) for the thread connection; When a thread throws an uncaughtException, run() returns and the uncaughtException method is called before the thread terminates
The demo:
public class ThreadMonitorDemo{ volatileboolean inited = false; static int threadIndex = 0; final static LoggerLOGGER = Logger.getAnonymousLogger(); final BlockingQueue
channel = new ArrayBlockingQueue
( 100); public static void main (String[] args) throwsInterruptedException { ThreadMonitorDemothreadMonitorDemo = new ThreadMonitorDemo(); threadMonitorDemo.init(); for ( int i =0; i < 100; i++) { threadMonitorDemo.service( “test- ” + i); } Thread.sleep(2000) ; System.exit(0 ); } privatesynchronized void init(){ if(inited) { return; } System.out .println(“init—-“) ; WorkerThreadworkerThread = new WorkerThread(); workerThread.setName(“Worker0-” + threadIndex ); / / thread connection for a uncaughtExceptionHandler workerThread. SetUncaughtExceptionHandler (new ThreadMonitor ()); workerThread.start(); inited = true; } privatevoid service(Stringmessage) throws InterruptedException{ channel .put(message); } privateclass WorkerThread extends Thread { @Override publicvoid run (){ System.out .println(“dosomething important…” ); Stringmsg; try { for (;; ) { msg = channel .take(); process(msg); } }catch (InterruptedException e) { } } privatevoid process(Stringmessage) throws InterruptedException{ System.out .println(message); if ((int ) (Math.random() * 100 ) < 2) { thrownew RuntimeException( “test” ) ; } Thread.sleep( 100 ) ; } } privateclass ThreadMonitor implements Thread.UncaughtExceptionHandler { @Override publicvoid uncaughtException (Threadt , Throwable e) { System.out .println( “currentthread is ” + Thread.currentThread() + “it is still alive:%s” + t.isAlive()) ; StringthreadInfo = t.goetName (); LOGGER .log(Level.SEVERE , threadInfo + “terminated: ” , e) ; // Create and start the replacement thread logger. info(“About to restart “+ threadInfo); // Reset thread start flag inited = false; init() ; }}}
If a thread does not have an associated UncaughtExceptionHandler instance, the uncaughtException method of the thread group will be called before the thread terminates abnormally. The uncaughtException method of a thread group calls the method of its parent thread group and passes the same two parameters
Organized and disciplined: Thread factories
ThreadFactory Creates a factory method for a thread:
public Thread newThread(Runnable r)
Four, thread suspension and recovery
Thread.suspend() and thread.resume () are both obsolete methods. Suspend (which has the same meaning as pause) and resume(which has the same meaning as wake up). Alternatives after obsolescence:
Set a thread pending flag that the thread checks before each time-consuming operation. If the flag should be pending, object.wait ()/ condition.await () is paused. Until another thread resets the pending flag and wakes it up.
public class PauseControl extends ReentrantLock { private static final long serialVersionUID = 21321213213131L; Private volatile Boolean SUSPENDED = false; private final Condition condSuspended = newCondition();/ * * *To suspend a threadThe equivalent of Thread.suspend() */ public void requestPause() { suspended = true; } / * * *Restore the threadThe equivalent of Thread.resume() */ public void proceed() { lock(); try { suspended = false; condSuspended.signalAll(); } finally { unlock(); }}/ * * *The current thread is only in thread suspension flag is nottrueBefore performing the specified target action * @param targetAction * @throws InterruptedException */ public void pauseIfNeccessary(Runnable targetAction) throws InterruptedException { lock(); try { while (suspended) { condSuspended.await(); } targetAction.run(); } finally { unlock(); }}}Copy the code