Summary
User expectations can show excellent performance. To meet this expectation, your program is often used in threads. In this article we started practicing using threads. You will learn threads, threads, and runnable.
Users don't like software that is slow. When a user clicks on a mouse, they hope that the program immediately responds to their request, even if the program is in the time of operation, such as a very long document re-edited page number or waiting for a network operation. Procedures for users in response to users are poor. In order to improve program performance, developers generally use threads.
This article is the first part of the exploration thread. Although you may think thread is a thing that is difficult to master, I intend to show you that thread is easy to understand. In this article, I will introduce you to threads and threads, and discuss Runnable. In addition, in the later article, I will explore synchronous (by lock), synchronous issues (such as dead locks), waiting / notify mechanisms, timing arrangements (priority and no priority), thread interrupts, timers, volatile Sex, thread groups and thread local variables.
Read the entire series of thread design:
· Part 1: Introduce threads and threads, and Runnable
· Part 2: Use synchronization to enable thread serialization to access key code part
note
This article and the three related thread exercises in its app are different from applets. However, I am using most applications introduced in the app to Applets. The main difference is: For safety reasons, not all thread operations can be placed in an applet (I will discuss Applets in later articles).
What is thread?
The concept of thread is not difficult to grasp: it is a separate execution channel of the program code. When a plurality of threads are executed, the channels of one thread via the same code are usually different from others. For example, it is assumed that one thread executes byte code that corresponds to the IF portion of an IF-ELSE statement, and the other thread is performing byte code equivalent to the ELSE portion. How does JVM keep track of each thread? JVM calls the stack for each thread itself. In addition, track the current command byte code, the method stack tracks the local variable, the JVM passes to a method of parameters, and the return value of the method.
This behavior is called multi-thread when multiple threads perform byte code sequences in the same program. Multi-threading is conducive to procedures:
• Multithreading GUI (Graphical User Interface) program can still maintain a response to the user, such as rebuilt page number or print a document.
· The program with threads is generally completed faster than those who have no threads. This especially performance is running on a multiprocessor machine in a multiprocessor machine, and every thread has its own processor.
Java completes multithreading through the Java.lang.Thread class. Each thread object describes a separate execution thread. Those run () methods that run in the thread. Because the default Run () method does not do, you must create a Thread subclass and overload Run () to complete useful work. Exercise List 1 gadgets a thread and multi-thread in Thread:
List 1. ThreadDemo.java
// ThreadDemo.java
Class ThreadDemo
{
Public static void main (string [] args)
{
Mythread MT = new mythread ();
Mt.start ();
For (int i = 0; i <50; i )
System.out.Println ("i =" i ", i * i =" i * i);
}
}
Class mythread extends thread {
Public void Run ()
{
For (int count = 1, row = 1; ROW <20; Row , Count )
{
For (int i = 0; i System.out.print ('*'); System.out.print ('/ n'); } } } Listing 1 shows the source code for applications consisting of THReadDemo and MythRead. Class ThreadDemo starts a thread related to its object and executes a code that prints a square table. Instead, Mythread is overlighted with Thread's Run () method prints (by standard input stream) a right angle triangle composed of star symbols. When you type Java ThreadDemo running an application, JVM creates a start thread that runs the main () method. By performing Mt.Start (), start thread tells the JVM to create a second thread that executes the byte code instruction of the Run () method containing the Mythread object. When the start () method returns, the start thread loop performs printing a square table, at which time another new thread performs a Run () method prints the right triangle. What is the output? You can see it running ThreadDemo. You will notice that the output of each thread is alternate with each other. Such results are because the two threads send their output to the same standard output stream. note Most (not all) JVM devices use the thread performance of the lower platform. Because those performance is a platform-specific, your multi-threaded output order may be different from the order of other people's other outputs. This difference is due to timing arrangements, I will discuss this topic later. Thread class To read multithreaded code, you must first understand a variety of ways to create a Thread class. This method will explore these methods. Clearly, you will learn how to start threads, name your thread, make threads sleep, decide if a thread is activated, associate a thread with another thread, and list all activation in the thread group and subgroups in the current thread the rout. I will also discuss the contrast of thread debug assist procedures and user threads and supervision threads. I will meditate on the remaining part of the thread method in the later article, except for the way Sun does not agree. caveat Sun has some unidentified thread types, such as suspend () and resume () because they can lock your programs or destroy objects. So, you don't have to call them in your code. Considering the SDK files for these method workspaces, I don't include these methods in this article. Construct thread THREAD has eight constructors. The simplest is: Thread (), create a Thread object with a default name · Thread (String Name), create a Thread object with the name of the specified Name parameter The next simplest constructor is Thread (Runnable Target) and Thread (Runnable Target, String Name). These constructors are the same as those described above in addition to the RunNable parameters. Different: the runnable parameter identifies an object other than the thread of the RUN () method. (You will learn Runnable later in this article) The last few constructors are Thread (String Name), Thread (Runnable Target), and Thread (Runnable Target, String Name). However, the final constructor includes a ThreadGroup parameter for organizing intent. One of the last four constructors, Thread (ThreadGroup Group, Runnable Target, String Name, long stacksize), is interested in making you specifying the size of the thread method calling the stack. It is very helpful to specify that the size will prove that in the use of the recursive method (a technique whose method is constantly repeating itself), it is very helpful. By explicitly set the stack size, you can sometimes prevent STACKOVERFLOWERRORS. However, too general leads to OutofMemoryErrorS. Similarly, Sun will call the size of the stack as a platform dependence. Dependent platform, method calls the size of the stack may change. Therefore, you carefully consider your program branches carefully before Write THREAD (ThreadGroup Group, Runnable Target, String Name, long stacksize). Start your load tool Threads are similar to the vehicle: they move the program from the beginning to the end. Thread and Thread subclass objects are not threads. They describe the properties of a thread, such as name and code containing threads (via a RUN () method). When a new thread performs Run (), another thread is positively: the start () method of the Thread or its subclass object. For example, to start the second thread, the application's start thread - it performs main () - call start (). The thread operation code that is operated with the JVM and the platform ensures that the thread correctly initializes and invokes the RUN () method of the Thread or its sub-object. Once START () is complete, multiple lines are running. Because we tend to think in a linear way, we often find that it is difficult to understand concurrency (simultaneous) behavior when two or more threads are running. Therefore, you should look at the chart showing the display and time to perform (its location). The picture below is such a chart. With time compare a behavior of starting thread and a new thread execution location The chart shows several important period: · Start the initialization of threads · Thread starts to execute main () instant · Thread starts to perform start () instant · Start () creates a new thread and returns the moment of main () · Initialization of new thread · The new thread began to perform the moment of Run () · Different moments of each thread end Note that the initialization of the new thread, is the execution of Run (), and its end of its end occurs simultaneously with the start thread. caveat After a thread calls start (), when the Run () method exits, the method will cause start () to throw a java.lang.illegalthreadStateException object. How to use the name During a debug session, the user-friendly way is partially distinguished from another thread. To distinguish one of the threads, Java gives a name to a thread. Thread default name is a short-term hyphen and a zero-start number symbol. You can accept Java's default thread name or choose to use yourself. In order to be able to customize the name, Thread provides a constructor with an Name parameter and a setName (String Name) method. Thread also provides a getName () method to return the current name. Table 2 shows how to create a custom name through Thread (String Name) and retrieve the current name by calling getName () in the Run () method: Table 2.NameThatthread.java // NameThatthread.java Class NameThatthread { Public static void main (String [] args) { Mythread MT; IF (args.length == 0) Mt = new mythread (); Else Mt = new mythread (args [0]); Mt.start (); } } Class mythread extends thread { Mythread () { // Compiler Create an equivalent of the byte code in super () } Mythread (String Name) { Super (name); // Pass the name to the THREAD super class } Public void Run () { System.out.println ("My Name IS:" GetName ()); } } You can pass an optional Name parameter to mythread at the command line. For example, Java NameThatthread X establishes X as the name of the thread. If you specify a name fails, you will see the output below: My name is: thread-1 If you like, you can change the super (name) call into setName (String Name) call in Mythread (String Name) constructor - a method for calling the same to establish a thread name as a way As a super (name) I have reserved it to you as an exercise. note Java mainly assigns names to threads running the main () method, start thread. You particularly look at the default exceptions of the JVM of the thread "Main" to process print messages when the start thread is thrown out of an exception. Sleep or stop sleep Behind this column, I will introduce you to you - repeat the graphics on a surface, which is slightly different from the completion of a sports screen. To complete the animation, a thread must be suspended when it displays two consecutive pictures. Call Thread's Static Sleep (Long Millis) method forces a thread to stop Millis milliseconds. Another thread may interrupt the hibernated thread. If this happens, the hibernated thread will wake up and throw an InterruptedException object from the Sleep (long Millis) method. As a result, the code that calls SLEEP (long Millis) must be in a try code block - or the code method must include InterruptedException in its own Throws clause. To demonstrate Sleep (Long Millis), I wrote a Calcpi1 application. This application starts a new thread to make the value of the mathematical constant Pi with a mathematical algorithm. When the new thread is calculated, the start thread is started to abort 10 milliseconds by calling Sleep (long Millis). After starting the line, it will print the value of the PI, where the new thread is stored in the variable PI. Table 3 gives the source code of Calcpi1: Table 3. Calcpi1.java // Calcpi1.java Class Calcpi1 { Public static void main (string [] args) { Mythread MT = new mythread (); Mt.start (); Try { Thread.sleep (10); // Sleep 10 ms } Catch (InterruptedException E) { } System.out.println ("pi =" mt.pi); } } Class mythread extends thread { Boolean negative = true; Double Pi; // The default is initialized to 0.0 Public void Run () { For (int i = 3; i <100000; i = 2) { IF (Negative) Pi - = (1.0 / i); Else Pi = (1.0 / i); NEGATIVE =! } Pi = 1.0; PI * = 4.0; System.out.println ("Finished Calculating Pi"); } } If you run this program, you will see the output as follows (but may also be different): Pi = -0.2146197014017295 Complete calculation PI Why is the output incorrect? After all, the value of the PI should be approximately equal to 3.14159. The answer is: Start the thread awake too fast. When the new thread is just starting to calculate the PI, the start thread wakes up to read the current value of the PI and print it. We can compensate by adding 10 millisecond delays to a longer value. This longer value (unfortunately it relies on the platform) will give the new thread a chance to complete the calculation before starting the line. (Later, you will learn a technology that does not rely on the platform, it will prevent the startline from being built until the new thread is completed.) note Threads simultaneously provide a Sleep (Long Millis, int NANOS) method, which will thread Millis milliseconds and Nanos nanoseconds. Because most JVM-based platforms do not support the decomposition of nanoseconds, the JVM thread processing code enters the nanosecond number to the approximate value of millisecond numbers. If a platform does not support millisecondary decomposition, JVM thread processing code will be approximately multiple of the minimum level of milliseconds to support the minimum level of the platform. Is it dead or live? When a program is called the Start () method, there is a period of time (for initialization) before a new thread calls RUN (). After run () returns, there is a period of time before the JVM clear thread. JVM believes that the thread immediately activates a thread call Run (), and after the thread executes Run () and Run () returns. During this time interval, thread's isalive () method returns a Boolean true value. Otherwise, the method returns a false value. Isalive () is helpful in a thread that needs to wait for another thread to complete its Run () method before the first thread can check the results of other threads. In essence, those threads need to wait for a while loop. When IsAlive () returns true value for other threads, the Waiting thread calls Sleep (Long Millis, Int Nanos) periodically (avoiding more CPU loops). Once isalive () returns a false value, wait for the thread to check the results of other threads. Where will you use this technology? For the starter, a modified version of a Calcpi1, where is the thread waiting for the new thread to be completed before the value of the PI is printed? Table 4's Calcpi2 source code demonstrates this technology: Table 4. Calcpi2.java // Calcpi2.java Class Calcpi2 { Public static void main (string [] args) { Mythread MT = new mythread (); Mt.start (); While (mt.isalive ()) Try { Thread.sleep (10); // Sleep 10 ms } Catch (InterruptedException E) { } System.out.println ("pi =" mt.pi); } } Class mythread extends thread { Boolean negative = true; double pi; // default initialization into 0.0 Public void Run () { For (int I = 3; i <100000; i = 2) { IF (Negative) Pi - = (1.0 / i); Else Pi = (1.0 / i); NEGATIVE =! } Pi = 1.0; PI * = 4.0; System.out.println ("Finished Calculating Pi"); } } The start thread of Calcpi2 is hibernated in 10 milliseconds until mt.isalive () returns a false value. When those occurring, the start thread exits and prints the contents of PI from its While loop. If you run this program, you will see the output (but not necessarily the same): Complete calculation PI Pi = 3.1415726535897894 This is not, now it looks more accurate? note A thread may call it itself by the isalive () method. However, this is meaningless because isalive () will return true value. Fitness Because the While loop / isalive () method / sleep () method technology proves is useful, Sun is packaged in a combination of three methods: join (), Join (long Millis) and Join (Long Millis, Int Nanos) ). When the current thread wants to wait for the end of the other thread, call JOIN (). Conversely, when it wants to wait for any thread to wait for other threads to end or wait until Millis milliseconds and Nanos nanosecond combinations, the current thread calls Join (Long Millis) or JOIN (Long Millis, Int Nanos). (As a Sleep () method, the JVM thread processing code will give the parameter value of Join (long Millis) and Join (INT NANOS).) Table 5's Calcpi3 source code demonstrates a call to join (): Table 5. Calcpi3.java // Calcpi3.java Class Calcpi3 { Public static void main (string [] args) { Mythread MT = new mythread (); Mt.start (); Try { Mt.join (); } Catch (InterruptedException E) { } System.out.println ("pi =" mt.pi); } } Class mythread extends thread { Boolean negative = true; Double Pi; // Default initialization into 0.0 Public void Run () { For (int I = 3; i <100000; i = 2) { IF (Negative) Pi - = (1.0 / i); Else Pi = (1.0 / i); NEGATIVE =! } Pi = 1.0; PI * = 4.0; System.out.println ("Finished Calculating Pi"); } } The start thread of Calcpi3 is waiting to end with the Mythread object to end the thread referenced by the MT. Then start the value of the thread print PI, which is the same as the output of CALCPI2. caveat Don't try to connect the current thread with your own, because it will wait forever. How to use the name During a debug session, the user-friendly way is partially distinguished from another thread. To distinguish one of the threads, Java gives a name to a thread. Thread default name is a short-term hyphen and a zero-start number symbol. You can accept Java's default thread name or choose to use yourself. In order to be able to customize the name, Thread provides a constructor with an Name parameter and a setName (String Name) method. Thread also provides a getName () method to return the current name. Table 2 shows how to create a custom name through Thread (String Name) and retrieve the current name by calling getName () in the Run () method: Table 2.NameThatthread.java // NameThatthread.java Class NameThatthread { Public static void main (string [] args) { Mythread MT; IF (args.length == 0) Mt = new mythread (); Else Mt = new mythread (args [0]); Mt.start (); } } Class mythread extends thread { Mythread () { // Compiler Create an equivalent of the byte code in super () } Mythread (String Name) { Super (name); // Pass the name to the THREAD super class } Public void Run () { System.out.println ("My Name IS:" GetName ()); } } You can pass an optional Name parameter to mythread at the command line. For example, Java NameThatthread X establishes X as the name of the thread. If you specify a name fails, you will see the output below: My name is: thread-1 If you like, you can change the super (name) call into setName (String Name) call in Mythread (String Name) constructor - a method for calling the same to establish a thread name as a way As a super (name) I have reserved it to you as an exercise. note Java mainly assigns names to threads running the main () method, start thread. You particularly look at the default exceptions of the JVM of the thread "Main" to process print messages when the start thread is thrown out of an exception. Sleep or stop sleep Behind this column, I will introduce you to you - repeat the graphics on a surface, which is slightly different from the completion of a sports screen. To complete the animation, a thread must be suspended when it displays two consecutive pictures. Call Thread's Static Sleep (Long Millis) method forces a thread to stop Millis milliseconds. Another thread may interrupt the hibernated thread. If this happens, the hibernated thread will wake up and throw an InterruptedException object from the Sleep (long Millis) method. As a result, the code that calls SLEEP (long Millis) must be in a try code block - or the code method must include InterruptedException in its own Throws clause. To demonstrate Sleep (Long Millis), I wrote a Calcpi1 application. This application starts a new thread to make the value of the mathematical constant Pi with a mathematical algorithm. When the new thread is calculated, the start thread is started to abort 10 milliseconds by calling Sleep (long Millis). After starting the line, it will print the value of the PI, where the new thread is stored in the variable PI. Table 3 gives the source code of Calcpi1: Table 3. Calcpi1.java // Calcpi1.java Class Calcpi1 { Public static void main (string [] args) { Mythread MT = new mythread (); Mt.start (); Try { Thread.sleep (10); // Sleep 10 ms } Catch (InterruptedException E) { } System.out.println ("pi =" mt.pi); } } Class mythread extends thread { Boolean negative = true; Double Pi; // The default is initialized to 0.0 Public void Run () { For (int I = 3; i <100000; i = 2) { IF (Negative) Pi - = (1.0 / i); Else Pi = (1.0 / i); NEGATIVE =! } Pi = 1.0; PI * = 4.0; System.out.println ("Finished Calculating Pi"); } } If you run this program, you will see the output as follows (but may also be different): Pi = -0.2146197014017295 Complete calculation PI Why is the output incorrect? After all, the value of the PI should be approximately equal to 3.14159. The answer is: Start the thread awake too fast. When the new thread is just starting to calculate the PI, the start thread wakes up to read the current value of the PI and print it. We can compensate by adding 10 millisecond delays to a longer value. This longer value (unfortunately it relies on the platform) will give the new thread a chance to complete the calculation before starting the line. (Later, you will learn a technology that does not rely on the platform, it will prevent the startline from being built until the new thread is completed.) note Threads simultaneously provide a Sleep (Long Millis, int NANOS) method, which will thread Millis milliseconds and Nanos nanoseconds. Because most JVM-based platforms do not support the decomposition of nanoseconds, the JVM thread processing code enters the nanosecond number to the approximate value of millisecond numbers. If a platform does not support millisecondary decomposition, JVM thread processing code will be approximately multiple of the minimum level of milliseconds to support the minimum level of the platform. Is it dead or live? When a program is called the Start () method, there is a period of time (for initialization) before a new thread calls RUN (). After run () returns, there is a period of time before the JVM clear thread. JVM believes that the thread immediately activates a thread call Run (), and after the thread executes Run () and Run () returns. During this time interval, thread's isalive () method returns a Boolean true value. Otherwise, the method returns a false value. Isalive () is helpful in a thread that needs to wait for another thread to complete its Run () method before the first thread can check the results of other threads. In essence, those threads need to wait for a while loop. When IsAlive () returns true value for other threads, the Waiting thread calls Sleep (Long Millis, Int Nanos) periodically (avoiding more CPU loops). Once isalive () returns a false value, wait for the thread to check the results of other threads. Where will you use this technology? For the starter, a modified version of a Calcpi1, where is the thread waiting for the new thread to be completed before the value of the PI is printed? Table 4's Calcpi2 source code demonstrates this technology: Table 4. Calcpi2.java // Calcpi2.java Class Calcpi2 { Public static void main (string [] args) { Mythread MT = new mythread (); Mt.start (); While (mt.isalive ()) Try { Thread.sleep (10); // Sleep 10 ms } Catch (InterruptedException E) { } System.out.println ("pi =" mt.pi); } } Class mythread extends thread { Boolean negative = true; Double Pi; // Default initialization into 0.0 Public void Run () { For (int I = 3; i <100000; i = 2) { IF (Negative) Pi - = (1.0 / i); Else Pi = (1.0 / i); NEGATIVE =! } Pi = 1.0; PI * = 4.0; System.out.println ("Finished Calculating Pi"); } } The start thread of Calcpi2 is hibernated in 10 milliseconds until mt.isalive () returns a false value. When those occurring, the start thread exits and prints the contents of PI from its While loop. If you run this program, you will see the output (but not necessarily the same): Complete calculation PI Pi = 3.1415726535897894 This is not, now it looks more accurate? note A thread may call it itself by the isalive () method. However, this is meaningless because isalive () will return true value. Fitness Because the While loop / isalive () method / sleep () method technology proves is useful, Sun is packaged in a combination of three methods: join (), Join (long Millis) and Join (Long Millis, Int Nanos) ). When the current thread wants to wait for the end of the other thread, call JOIN (). Conversely, when it wants to wait for any thread to wait for other threads to end or wait until Millis milliseconds and Nanos nanosecond combinations, the current thread calls Join (Long Millis) or JOIN (Long Millis, Int Nanos). (As a Sleep () method, the JVM thread processing code will give the parameter value of Join (long Millis) and Join (INT NANOS).) Table 5's Calcpi3 source code demonstrates a call to join (): Table 5. Calcpi3.java // Calcpi3.java Class Calcpi3 { Public static void main (string [] args) { Mythread MT = new mythread (); Mt.start (); Try { Mt.join (); } Catch (InterruptedException E) { } System.out.println ("pi =" mt.pi); } } Class mythread extends thread { Boolean negative = true; Double Pi; // Default initialization into 0.0 Public void Run () { For (int I = 3; i <100000; i = 2) { IF (Negative) Pi - = (1.0 / i); Else Pi = (1.0 / i); NEGATIVE =! } Pi = 1.0; PI * = 4.0; System.out.println ("Finished Calculating Pi"); } } The start thread of Calcpi3 is waiting to end with the Mythread object to end the thread referenced by the MT. Then start the value of the thread print PI, which is the same as the output of CALCPI2. caveat Don't try to connect the current thread with your own, because it will wait forever. Query active thread In some cases, you may want to know which threads in your program are activated. Thread supports a pair method to help you complete this task: activeCount () and enumerate (thread [] thdarray). But those methods are only working in the thread group of the current thread. In other words, those methods only identify the active thread of the same thread group belonging to the current thread. (I will discuss threading groups in the next series of articles.) Static ActiveCount () method Returns the number of threads that are active in the thread group in the current thread. A program utilizes the integer return value of this method to set the size of a THREAD reference array. Retrieve those references, the program must call the static ENUMERATE (THREAD [] THDARRAY method. The integer return value of this method determines the total number of Enumerate (Thread [] Thdarray) in the Thread reference stored in the array. To see how these methods work together, please see Table 6: Table 6. Census.java // census.java Class CenSUS { Public static void main (string [] args) { Thread [] threads = new thread [threeRead.activecount ()]; INT n = thread.enumerate (threads); For (int i = 0; i System.out.println (threads [i] .tostring ()); } } At runtime, this program will produce the following output: Thread [main, 5, main] The output is displayed, and the start thread is running. The on the left main represents the name of the thread. 5 Display the priority of the thread, the main MAIN represents the thread group. You may be very disappointed that you can't see any system threads, such as garbage collector threads in the output. That limit is generated by thread's enumerate (thread [] thdarray) method, which only asks the active thread of the current thread thread group. However, the ThreadGroup class contains a variety of enumerate () methods allow you to capture references to all active threads without the threaded group. In the series of series, I will show you how to list all references when I discussed ThreadGroup. caveat When you reiterate an array, do not rely on the return value of ActiveCount (). If you do this, your program will throw a risk of NullPointerexception objects. why? Between call activecount () and enumerate (Thread [] Thdarray), one or more threads may end. As a result, enumerate (thread [] thdaRray) can copy a few thread reference into an array. Therefore, only consider the return value of the ActiveCount () as the maximum value of the array. Similarly, consider the return value of Enumerate (Thread [] ThdArray as the number of active threads when the method is called in one program. Antisocar If your program fails and you suspect that the problem is in the thread, you can learn more details of the thread by calling Thread Dumpstack () and TSTRING (). The static dumpstack () method provides a new Exception ("stack trace"). PrintStackTrace () package, print a stack that tracks the current thread. TSTRING () Returns a string of the name, priority, and thread group of threads based on the following format: thread [thread-name, priority, thread-group]. (you will learn more about priority in the series Knowledge of rights.) skill In some places, this article refers to the concept of current threads. If you need to access the Thread object that describes the current thread, call the Static CurrentThread () method of THREAD. Example: thread current = thread.currentthread (). Level system Not all threads are created equally. They are divided into two categories: users and supervision. A user thread performs a very important job for program users, and the work must be completed before the program ends. Instead, a supervision thread performs logistics (such as garbage collection) and other background tasks that may not contribute to the main work of the application but continue its main work for the application. Unlike the user thread, the supervision thread does not need to be completed before the application ends. When an application starts thread (which is a user thread), JVM checks if there is any other user thread that is running. If there is, JVM will prevent the application from ending. Otherwise, JVM will end the application regardless of whether the monitoring thread is running. When a thread calls a straw object's START () method, the new starting thread is a user thread. It is default. To create a thread as a supervision thread, the program must call a setDaemon (Boolean Isdaemon) method with a Boolean truth parameter before calling start (). Later, you can check if a thread is a supervision thread by calling the IsDaemon () method of THREAD. If it is a monitoring thread that returns a Boolean true value. In order to let you try the user and supervision thread, I wrote a USERDAEMONTHREADDEMO: Table 7. UserdaemonthreadDemo.java // UserdaemonthreadDemo.java Class userdaemonthreaddemo { Public static void main (string [] args) { IF (args.length == 0) New mythread () .start (); Else { Mythread MT = new mythread (); Mt.SetDaemon (TRUE); Mt.start (); } Try { Thread.sleep (100); } Catch (InterruptedException E) { } } } Class mythread extends thread { Public void Run () { System.out.println ("daemon is" isdaemon ()); While (True); } } After compiling the code, run UserDaemonthreadDemo through the Java2 SDK Java command. If you do not use the command line parameters, such as Java UserDaemonthreadDemo, new mythread () .Start () is executed. This code snippet starts a user thread that prints the DAEMON IS FALSE before entering an infinite loop. (You must press Ctrl-C or a combination button that ends an unlimited loop.) Because the new thread is a user thread, the application remains running after the start of the thread. However, if you specify at least one command line parameter, such as Java UserDaemonThreadDemo X, Mt.SetDaemon (TRUE) is executed and the new thread will be a supervision thread. As a result, once the thread is started from 100 milliseconds, the new supervision thread will end. caveat If the thread starts to execute, call the setDaemon (Boolean Isdaemon) method, the setDaemon method will throw an ILLEGALTHREADSTATEEXCEPTION object. Runnable After learning the previous part, you may think that introducing multithreaded into a class always requires you to extend Thread and overload your subclass with the Thread's Run () method. However, it is not always a choice. Java enforces the inheritance of two or more superclars. As a result, if a class expands a wireless class, that class cannot extend Thread. If a limit, how can I introduce multiple threads into a class that has expanded other classes? Fortunately, Java designers have realized that it is impossible to create Thread subclasses. This results in generating a java.lang.Runnable interface and a Thread constructor with Runnable parameters, such as Thread (Runnable Target). The runnable interface declares a single method signature: Void Run (). This signature is the same as the thread's Run () method and as a thread's execution portal. Because runnable is an interface, any class can implement an interface by including an IMPLEMENTS clause to a class head and providing an appropriate Run () method. In execution time, program code can create an object or runnable from that class and pass the RunNable reference to a suitable Thread constructor. The constructor and the Thread object stored together this reference and ensures a new thread to call the run () method of runnable after calling the Thread object. Demonstration is true for Table 8: Table 8.RunnableDemo.java // RunnableDemo.java Class RunnableDemo { Public static void main (string [] args) { Rectangle R = New Rectangle (5, 6); R.DRAW (); // Different rectangles with the width and height of the random selection NEW Rectangle (); } } Abstract Class Shape { Abstract void Draw (); } Class Rectangle Extends Shape IMPLEments Runnable { Private int W, H; Rectangle () { // Create a new Thread object that binds this runnable and starts a call to call this runnable // Run () method thread New thread (this) .start (); } Rectangle (int W, INT H) { IF (W <2) Throw new IllegalarGumentexception ("w value" w "<2"); IF (h <2) Throw New IllegalargumentException ("H Value" H "<2"); THIS.W = W; THIS.H = H; } Void Draw () { For (int C = 0; c System.out.print ('*'); System.out.print ('/ n'); For (int R = 0; R { System.out.print ('*'); For (int C = 0; c System.out.print (''); System.out.print ('*'); System.out.print ('/ n'); } For (int C = 0; c System.out.print ('*'); System.out.print ('/ n'); } Public void Run () { For (int i = 0; i <20; i ) { W = RND (30); IF (W <2) W = 2; H = rND (10); IF (h <2) H = 2; Draw (); } } INT RND (INT LIMIT) { // Returns a random number X within 0 <= x Return (int) ("math.random () * limited; } } RunnableDemo consists of class RunnableDemo, Shape, and Rectangle. Class RunnableDemo drives applications by creating a Rectangle object - by calling the object's DRAW () method - and the Rectangle class that is not made by creating the second. Instead, Shape and Rectangle constitute a SHAPE-based class. Shape is abstract because it provides an abstract draw () method. Various Shape classes, such as Rectangle, extended Shape, and describing how they draw their own overload DRAW (). In the future, I may decide to introduce some additional Shape classes, create a shape array, and ask each Shape element to draw itself by calling the shape DRAW () method. RunnableDemo is generated as a simple program without multi-threaded. Behind I decided to introduce multithreaded to Rectangle so I can use a variety of widths and highly painted rectangles. Because Rectangle extension Shape (for later polymorphism), I don't have other options that only let Rectangle implement runnable. Similarly, in the Rectangle () constructor, I have to bind a Rectangle Runnable to a new Thread object and call the Start () method of Thread () to start a new thread to call the Rectangle's Run () method draws rectangle. Because the new output of RunnableDemo included in this article is too long, I suggest you compile and run the program yourself. skill When you face a class that is not able to extend thread, you will choose which method you want to implement Runnable? If this class has expanded other classes, you must implement Runnable. However, if this class does not expand other classes, consider the name of the class. The name will suggest that the object of this class is not positive is negative. For example, Name Ticker suggests that it is positive. Therefore, the Ticker class will extend Thread, and the Ticker object will be used as a dedicated Thread object. Instead, Rectangle hints that the negative object -Rectangle object does not do anything to them. Therefore, the Rectangle class will implement RunNable, and the Rectangle object will use the Thread object (for test or other intentions) instead of becoming a dedicated Thread object. review The user expects the program to achieve excellent performance. One way is to complete those tasks with threads. A thread is an independent execution channel of a program code. Threads are beneficial to GUI-based procedures because they allow those programs to remain respond to users when performing other tasks. In addition, the threaded program is completely fast than the copies that have no threads. This is especially obvious for running on multi-processor machines, where each thread has its own processor. Thread and Thread subclass objects describe threads and related to those entities. For classes that cannot extend Thread, you have to create a runnable to utilize multithreaded advantages.