1. Thread Addition
Threads do not necessarily compete for CPU immediately after startup, but after using join() method, threads will first grab CPU. The sample code is as follows:
class Test implements Runnable{ public void run(){ for(int i = 1 ;i<=10;i++){ System.out.println(Thread.currentThread().getName()+"Shixundi"+i+"second"); } } } public class Demo1 { public static void main(String[] args) { Test t = new Test(); Thread t0 = new Thread(t); Thread t1 = new Thread(t); t0.start(); t1.start(); for(int i = 1 ;i<=10;i++){ System.out.println(Thread.currentThread().getName()+"Shixundi"+i+"second"); } } }
The results are as follows:

The main thread competes with the T0 and T1 threads for CPU, at which time the code is slightly modified:
class Test implements Runnable{ public void run(){ for(int i = 1 ;i<=10;i++){ System.out.println(Thread.currentThread().getName()+"Shixundi"+i+"second"); } } } public class Demo1 { public static void main(String[] args) throws InterruptedException { Test t = new Test(); Thread t0 = new Thread(t); Thread t1 = new Thread(t); t0.start(); /* * At this point, only the main thread and the T0 thread are available. * T0 Threads start but don't necessarily grab the CPU * But after using join() method * The main thread will give the CPU to the T0 thread */ t0.join(); t1.start(); for(int i = 1 ;i<=10;i++){ System.out.println(Thread.currentThread().getName()+"Shixundi"+i+"second"); } } }
The results are as follows:

Because the main thread gives the CPU to the T0 thread, only the T0 thread is executing the task at this time, so the result is that the T0 thread first circulates 10 times, then the main thread grabs the CPU and starts the T1 thread, and then the main thread competes with the T1 thread for the CPU.
Modify the sample code again and place t0.join() after the start of the T1 thread:
class Test implements Runnable{ public void run(){ for(int i = 1 ;i<=10;i++){ System.out.println(Thread.currentThread().getName()+"Shixundi"+i+"second"); } } } public class Demo1 { public static void main(String[] args) throws InterruptedException { Test t = new Test(); Thread t0 = new Thread(t); Thread t1 = new Thread(t); t0.start(); t1.start(); // Put t0.join() after the start of the T1 thread t0.join(); for(int i = 1 ;i<=10;i++){ System.out.println(Thread.currentThread().getName()+"Shixundi"+i+"second"); } } }
The results are as follows:

The result is that the join() method only keeps the main thread waiting and the other threads unaffected. At this time, t0.join() is placed after the T1 thread starts. When the main thread enters and waits, the T0 thread and the T1 thread still compete for the CPU. As long as the T0 thread finishes executing the task code, the main thread can start executing, and with the T1 thread. Start scrambling for CPU.
2. The correct stop of threads
How to stop the thread? Although the stop() method is available in the API documentation, it is outdated and currently can only wait for the thread to complete the task code and then stop naturally. But most of the threads use loops. In order to make the loops end, we should use the method of setting exit flag to stop the threads. The example code is as follows:
class Test implements Runnable{ //Create exit flag boolean flag = true; public void run(){ //Use exit logo while(flag){ System.out.println(Thread.currentThread().getName()+"Test thread startup"); } } } public class Demo2 { public static void main(String[] args) { Test t = new Test(); Thread t0 = new Thread(t); Thread t1 = new Thread(t); t0.start(); t1.start(); /* * Setting any method that can change the exit flag * For example, define a variable i * When i cycles to 500 * Change the exit flag to false * Realize the end of the loop for task code * To terminate the thread */ int i = 1 ; while(true){ if(i++==500){ t.flag=false; //End the Dead Cycle break; } } } }
The results are as follows:
It's not that you forget to upload pictures, but because the sample code itself runs without results. The reason for this phenomenon is that after the main thread starts the T0 and T1 threads, the CPU is still occupied by the main thread, so the main thread continues to execute downward and changes flag to false. So when the T0 and T1 threads grab the CPU, after judging that the exit flag is false, they directly skip the cycle and do nothing, so of course. No result. In view of this phenomenon, the following modifications are made to the code:
class Test implements Runnable{ boolean flag = true; public void run(){ while(flag){ System.out.println(Thread.currentThread().getName()+"Test thread startup"); /* * You can not use the sleep() method at this point * Threads will still stop normally * Use only to reduce the number of cycles * Easy to view results */ try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } } } } public class Demo2 { public static void main(String[] args) throws InterruptedException { Test t = new Test(); Thread t0 = new Thread(t); Thread t1 = new Thread(t); t0.start(); t1.start(); //The sleep() method here is essential Thread.sleep(20); int i = 1 ; while(true){ if(i++==500){ t.flag=false; break; } } } }
The results are as follows:

The way of modification is to add sleep() method after the start of T0 and T1 threads, so that the currently running threads give up CPU execution dormancy, that is to say, the main threads dormancy for 20 milliseconds, then the T0 and T1 threads will go to execute task codes separately, and the main threads will preempt the CPU again and change the exit mark value downward. After that, the T0 and T1 threads end the loop by judging that flag is false, and the threads end accordingly.
3. Error Stopping of Threads
Although the interrupt() method is an interrupt thread, it can not stop the thread correctly.
API This method is mentioned in the document.Interrupt statusThis concept needs to be understood in two ways:
public static boolean interrupted()
interrupted() method is a static method to test whether the current thread has been interrupted. The interrupt state of the thread is cleared by this method. If the current thread has been interrupted, return true or false.
public boolean isInterrupted()
The isInterrupted() method is an instance method used to test whether the thread has been interrupted. The interrupt state of threads is not affected by this method. If the thread has been interrupted, return true or false.
Simply put, both methods return a boolean type value to indicate whether our current thread is interrupted, when the thread is in certain conditions (see details). Java official API ) Calling the interrupt() method sets the interrupt state of the thread when none of them is valid. Then when we call interrupted() or isInterrupted() methods, we get a true value indicating that the thread has been interrupted. Among certain conditions, the focus is on this situation:
If the call to wait(), wait(long) or wait(long, int) methods of the Object class is blocked, or the join(), join(long), join(long, int), sleep(long), or sleep(long, int) methods of that class are blocked, the interrupt state will be cleared, and an InterruptedException will be received.
When a thread calls the above method, once the interrupted() method is called by other threads, it will receive an InterruptedException, which is why try-catch blocks are needed to capture exceptions when using the above method. Notice that the interrupt state will be cleared, which means that when we call interrupted() or isInterrupted() methods again, we will not get the correct return value. The sample code is as follows:
public class InterruptThread extends Thread{ public static void main(String[] args) { InterruptThread thread = new InterruptThread(); System.out.println("Start threads"); thread.start(); try { sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Interrupt thread"); thread.interrupt(); try { sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Program Stop"); } public void run(){ while(true){ System.out.println("Threads are running..."); /* * Reduce the output of operation results * To output only one line of result information per second * Easy to view * Equivalent to sleep(1000) * Why not use sleep(1000) directly? */ long time = System.currentTimeMillis(); while((System.currentTimeMillis()-time<1000)){ } } } }
The run() method is an infinite loop of task code that always executes the output "Threads are running... ". When a thread is started, the output"Start Thread"will be output, and after 3 seconds of dormancy, the interrupt thread will be prompted. After 3 seconds of dormancy, the program will stop. Will the program stop?
The results are as follows:

It is obvious that the interrupt() method does not stop the thread, and of course, the correct thread stop method can be used to modify the above code:
public class InterruptThread extends Thread{ public static void main(String[] args) { InterruptThread thread = new InterruptThread(); System.out.println("Start threads"); thread.start(); try { sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Interrupt thread"); thread.interrupt(); try { sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Program Stop"); } public void run(){ //End the loop by modifying the exit flag while(!this.isInterrupted()){ System.out.println("Threads are running..."); long time = System.currentTimeMillis(); while((System.currentTimeMillis()-time<1000)){ } } } }
The results are as follows:

At this point, the thread stops correctly because it terminates the while loop by modifying the exit flag. Here's another explanation of the problem mentioned in the previous comment, why use while ((System. current Time Millis () - time < 1000){} instead of Thread.sleep(1000) directly, because when Thread calls the sleep(1000) method, the interrupt state is cleared and an exception is thrown, so the exit flag of this. Inist loop! Errupted () also fails, failing to return to the correct interrupt state, and thus the thread cannot stop.
4. Daemon threads
Daemon Thread refers to the thread that provides a general service in the background when the program runs. For example, garbage collection thread is a classic daemon thread, and this thread is not an indispensable part of the program. User Thread corresponds to the daemon thread. Therefore, when all non-daemon threads are finished, the program will stop regardless of whether the task code of the daemon thread has been executed or not.
When using daemon threads, you need to pay attention to a few points:
- Threads using setDaemon() must be started before the thread, that is, the start() method. Otherwise, an IllegalThreadStateException exception will be thrown, i.e., the running regular thread cannot be set as a daemon thread.
- New threads generated in daemon threads are also daemon threads.
- Keep in mind that daemon threads do not access inherent resources, such as files, databases, because it may interrupt at any time.
Converting a thread to a daemon thread can be achieved by calling setDaemon() of the Thread object. The sample code is as follows:
//Create daemon threads class DaemonThread implements Runnable{ public void run(){ for(long i = 0;i<9999999L;i++){ System.out.println("Daemon thread T1 Execution"+i+"second"); try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } } } } //Create user threads class UserThread extends Thread{ public void run(){ for(int i = 0;i<5;i++){ System.out.println("---User thread execution T0 Xing di"+i+"second---"); try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } } } } public class Demo3 { public static void main(String[] args) { DaemonThread dt = new DaemonThread(); UserThread ut = new UserThread(); Thread t0 = new Thread(ut); Thread t1 = new Thread(dt); //Set T1 thread to daemon thread t1.setDaemon(true); t0.start(); t1.start(); } }
The results are as follows:

The result shows that although the daemon thread has set enough cycles, the daemon thread also stops when the user thread has finished executing the task code.
Copyright Statement: Welcome to reprint, welcome to spread, but when reprinting, please indicate the author and the source of the original text, thank you for your cooperation! __