In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-10 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly explains "what is multithreaded source code". Interested friends may wish to take a look at it. The method introduced in this paper is simple, fast and practical. Next let the editor to take you to learn "what is multithreaded source code"!
Thread sleep
Sleep is a static method that has two overloaded methods, one of which requires passing in milliseconds, and the other requires both milliseconds and nanoseconds.
Introduction of sleep method
Public static void sleep (long millis) throws InterruptedException public static void sleep (long millis, int nanos) throws InterruptedException
The sleep method will put the current thread into hibernation for a specified number of milliseconds and suspend execution. Although a hibernation time is given, it is ultimately subject to the accuracy of the system timer and scheduler. A very important feature of hibernation is that it will not give up ownership of the monitor lock (monitor will be highlighted later in thread synchronization and locking). Let's take a look at a simple example:
Package com.wangwenjun,concurrent,chapter03;public class Threadsleeppublic static void main (String [] args) new Thread (()-> long startTime = System.currentTimeMillis (); sleep (2000000L); long endTime = System.currentTimeMillis (); System.out.printin (String.format ("Total spend% d ms", (endTime-startTime));}) .start () Long startTime = System.currentTimeMillis (); sleep (3000L); long endTime = System.currentTimeMillis (); System.out.printin (String.format ("Main thread total spend% d ms", (endTime-startTime);} private static void sleep (long ms) {try {Thread.sleep (ms);} catch (InterruptedException e) {}
In the above example, we sleep in the custom thread and the main thread respectively, and the sleep of each thread does not affect each other. Thread.sleep will only cause the current thread to sleep for a specified time.
Use TimeUnit instead of Thread.sleep
After JDK1.5, JDK introduced an enumeration TimeUnit, which provides a good encapsulation for the sleep method. Using it can save the conversion steps of time units. For example, if a thread wants to sleep for 3 hours, 24 minutes, 17 seconds and 88 milliseconds, it is very simple and elegant to use TimeUnit:
Thread.sleep (12257088L); TimeUnit.HOURS.sleep (3); TimeUnit MINUTES.sleep (24); TimeUnit, SECONDS sleep (17); TimeUnit.MILLISECONDS.sleep (88)
The same time expression, TimeUnit is obviously much clearer, the author strongly recommends that in the use of Thread.sleep, completely use TimeUnit to replace, because sleep can do, TimeUnit can all complete, and more powerful, in the later content of this book, I will all use TimeUnit instead of sleep.
Thread yield
Introduction of yield method
The yield method is a heuristic that alerts the scheduler that I am willing to give up my current CPU resources and ignores this reminder if CPU's resources are not tight.
Calling the yield method causes the current thread to switch from the RUNNING state to the RUNNABLE state, which is not commonly used:
Package com.wangwenjun.concurrent,chapter03;import java.util.stream.IntStream;public class ThreadYield {public static void main (String [] args) {IntStream.range (0,2) .mapToObj (ThreadYield::create) .forEach (Thread::start);} private static Thread create (int index) {return new Thread (()-> {/ / ① comments / / if (index = = 0) / / Thread, yield (); System.out.printin (index);});}}
If the above program is run many times, you will find that the output results are inconsistent, sometimes 0 is the first to print out, there are
Time is 1 first to print out, but when you open the comments section of the code, you will find that the order is always 0,10 because the first thread if the first access to CPU resources, it will be more modest, take the initiative to tell CPU scheduler is to put their own resources, but yield R is a hint (hint), CPU scheduler will not guarantee that every time will meet the yield prompt.
Yield sleep
After looking at the previous content, you will find that there is some confusion between yield and sleep. In previous versions of JDK1.5, the method of yield actually called sleep (O), but there was an essential difference between them, as follows.
□ sleep causes the current thread to pause for a specified time, without the consumption of CPU time slices.
□ yield is just a hint to the CPU scheduler, and if the CPU scheduler does not ignore this prompt, it will lead to
Causes the thread context to switch.
□ sleep causes the thread to block briefly, releasing CPU resources for a given amount of time.
□ yield puts the Thread in the RUNNING state into the RUNNABLE state (if the CPU scheduler does not ignore this prompt).
□ sleep almost 100% completes dormancy at a given time, and yield's hints are not guaranteed.
□ one thread sleep another thread calls interrupt will catch the interrupt signal, but yield will not.
Set the priority of the thread
□ public final void setPriority (int newPriority) sets the priority for threads.
□ public final int getPriority () gets the priority of the thread.
Introduction to thread priority
The process has the priority of the process, and the thread also has the priority. In theory, the thread with higher priority will get the opportunity to be scheduled by CPU first, but in fact, it is not always as you would like. Setting the priority of the thread is also a hint operation, as shown below.
□ for root users, it will hint the operating system you want to set the priority, otherwise it will be ignored.
□ if the CPU is busy, setting the priority may get more CPU time slices, but the level of the idle priority will hardly make any difference.
So don't try to bind specific businesses with thread priorities in your programming, or let the business rely heavily on thread priorities, which may disappoint you. To take a simple example, the effect may not be exactly the same in different cases, but we just want to give higher priority threads more opportunities to output information, as shown in the example code:
Package com.wangwenjun.concurrent.chapter03;public class Threadpriority {public static void main (String [] args) {Thread tl = new Thread (()-> {while (true) {System.out.printin ("tl");}}); tl setPriority (3); Thread T2 = new Thread (()-> {while (true) {System. Out. Printin (, lt2 ");}}); t2.setPriority (10); tl.start (); t2.start ();}}
Run the above program, you will find that the frequency of T2 is obviously higher, of course, this is also related to the author's current CPU resources, different situations of operation will have different results.
Thread priority source code analysis
To set the priority of a thread, you only need to call the setPriority method. Let's open the source code of Thread and analyze it together:
Public final void setPriority (int newPriority) {ThreadGroup g; checkAccess (); if (newPriority > MAX_PRIORITY | | newPriority
< MIN_PRIORITY) { throw new IllegalArgumentException();}if((g = getThreadGroup()) 1= null) {if (newPriority >G.getMaxPriority () {newPriority = g.getMaxPriority ();} setPriorityO (priority = newPriority);}}
Through the analysis of the above source code, we can see that the priority of a thread cannot be less than 1 or greater than 10. If the specified thread priority is greater than the priority of the group where the thread resides, then the specified priority will be invalidated and replaced by the highest priority of group. Let's prove it through an example:
Package com.wangwenjun.concurrent.chapter03;public class Threadpriority {public static void main (String [] args) {/ / define a thread group ThreadGroup group = new ThreadGroup ("test"); / / specify the priority of the thread group as 7group.setMaxPriority (7); / / define a thread to add the thread to the group Thread thread = new Thread (group, "test-thread"); / / attempt to set the priority of the thread to 10thread.setPriority (10) / / attempted System.out.printin (thread.getPriority ());}}
The above output is 7, not 10, because it exceeds the priority of the thread group
Some summaries about priorities
In general, the priority level is not set for the thread, still less will some businesses rely heavily on the priority of the thread, such as weight. It is not advisable to set the weight of a task with the help of priority. It is fine to use the default priority when defining threads. What is the default priority of the thread?
The default priority of a thread is the same as its parent class, which is usually 5. Because the priority of a main thread is 5, all threads derived from it are 5. The sample code is as follows:
Package com.wangwenjun.concurrent.chapter03;public class Threadpriority {public static void main (String [] args) {Thread tl = new Thread (); System.out,println ("tl priority" + tl.getPriority ()); Thread T2 = new Thread (()-> {Thread T3 = new Thread (); System.out.printIn ("T3 priority" + t3.getPriority ();}); T2 setPriority (6); T2 start (); System.out.printin ("T2 priority" + t2.getPriority ())
The output of the above program is that the priority of the tl is 5, because the priority of the main thread is 5, the priority of T2 is 6, because it is explicitly specified as 6, and the priority of T3 is 6, which is not explicitly specified, so it is consistent with the parent thread.
Get thread ID
Public long getld () gets the thread's unique ID, and the thread's ID will be unique in the entire JVM process.
And it is incremented step by step from 0. If you create a unique thread in the mainthread (main function) and find that it is not equal to 0 after calling getld (), you may wonder, shouldn't it start at 0? As mentioned before, when a JVM process starts, it actually opens up a lot of threads, and the self-increment sequence already has a certain consumption, so the thread we create ourselves is by no means thread 0.
Get the current thread
Public static Thread currentThread () is used to return a reference to the current thread of execution. Although this method is simple, it is widely used. We will use this method a lot later, to see a sample code:
Package com.wangwenjun.concurrent.chapter03;public class CurrentThread {public static void main (String [] args) {Thread thread = new Thread () {@ Overridepublic void run () {/ / always true System.out.printin (Thread.CurrentThread () = = this);}}; thread, start (); String name = Thread.CurrentThread (). GetName (); System.out.printIn ("main" .equals (name));}}
Both results of the above program running output are true.
Set the thread context class loader
The □ public ClassLoader getContextClassLoader () class loader that gets the thread context is simply which class loader the thread is loaded by, and maintains the same class loader as the parent thread if the thread context class loader is not modified.
□ public void setContextClassLoader (ClassLoader cl) sets the thread's classloader, which breaks the parent delegate mechanism of the JAVA classloader, which is sometimes referred to as the backdoor of the JAVA classloader.
We will focus on the thread context class loader in Chapter 11 of this book, and analyze why JDK developers have such a backdoor with the source code of the jdbc driver package.
Thread interrupt
Thread interrupt is a very important API and a frequently used method. There are several API related to thread interruption. In this section, we will also analyze Thread in detail in the source code.
□ public void interrupt () □ public static boolean interrupted () □ public boolean islnterrupted ()
Interrupt
The call to the following method puts the current thread into a blocking state, and the blocking can be broken by calling the current thread's interrupt method.
The wait method of □ Object. The wait (long) method of □ Object. The wait (long,int) method of □ Object. The sleep (long) method of □ Thread. The sleep (long,int) method of □ Thread. The join method of □ Thread. The join (long) method of □ Thread. The join (long,int) method of □ Thread. Io operation for □ InterruptibleChannel. The wakeup method of □ Selector.
□ other methods.
Some of the above methods will cause the current thread to enter a blocking state, and if another thread calls the blocked thread's interrupt method, it will break the blocking, so this method is sometimes called interruptible method. Remember, interrupting a thread does not mean the end of the thread's life cycle, it just interrupts the blocking state of the current thread.
Once a thread is interrupted while blocking, an exception called InterruptedException is thrown, which notifies the current thread like a signal (signal) that it has been interrupted. Let's take a look at an example:
Package com.wangwenjun,concurrent,chapter03;import java.util.concurrent .TimeUnit; public class Threadinterruptpublic static void main (String [] args) throws InterruptedException {Thread thread = new Thread (()-> {try {TimeUnit ·MINUTES.sleep (1);} catch (InterruptedException e) {System.out.printIn ("Oh, i am be interrupted.");},}); thread.start (); / / short block and make sure thread is started.TimeUnit, MILLISECONDS.sleep (2); thread, interrupt ();}}
The above code creates a thread and attempts to sleep for 1 minute, but unfortunately, it is interrupted by the main thread calling the interrupt method about 2 milliseconds later, and the result of the program execution is "Oh, i am be interrupted."
What exactly does the interrupt method do? There is a flag called interrupt flag inside a thread. If a thread is interrupt, its flag will be set, but if the current thread is blocked by executing interruptible methods, calling the interrupt method to interrupt it will cause flag to be cleared, which we will explain in detail later. It is also important to note that if a thread is already in a dead state, the interrupt that is tried on it will be ignored directly.
Islnterrupted
Islnterrupted is a member method of Thread, which mainly determines whether the current thread is interrupted. This method is only a judgment of the interrupt identity and will not affect any change in the identity. This is different from the interrupted we are about to learn. Let's take a look at a simple program:
Package com.wangwenjun, concurrent ·chapter03; import java.util.concurrent.TimeUnit;public class ThreadisInterrupted {public static void main (String [] args) throws InterruptedExceptionThread thread = new Thread () {@ Overridepublic void run () {while (true) {/ / do nothing, just empty loop.} Thread.start (); TimeUnit.MILLISEC0NDS.sleep (2); System.out.printf ("Thread is interrupted?% s\ n", thread.isInterrupted ()); thread.interrupt (); System.out.printf ("Thread is interrupted?% s\ n", thread.islnterrupted ());}}
A thread is defined in the above code, and an empty dead loop is written in the thread's execution unit (the run method). Why not write sleep? Because sleep is an interruptible method, it will capture the interrupt signal and interfere with the result of our program. The following is the result of running the program, remember to end the above program manually, or you can specify the above defined thread as the daemon thread, which will automatically exit when there are no non-daemon threads in the JVM as the end of the main thread.
Thread is interrupted? FalseThread is interrupted? True
After the interruptible method captures the interrupt signal (signal), that is, after capturing the InterruptedException exception, the interrupt logo will be erased. If you modify the above program slightly, you will find that the result of the program will be very different. The sample code is as follows:
Package com.wangwenjun.concurrent.chapter03;import java.util.concurrent.TimeUnit;public class ThreadisInterrupted {public static void main (String [] args) throws InterruptedException {Thread thread = new Thread () {@ Overridepublic void run () while (true) try {TimeUnit.MINUTES.sleep (1);} catch (InterruptedException e) {/ / ignore the exception//here the interrupt flag will be clear.System.out.printf ("I am be interrupted?% s\ n", islnterrupted ());} Thread.setDaemon (true); thread.start (); TimeUnit.MILLISECONDS.sleep (2); System.out.printf ("Thread is interrupted?% s\ n", thread.isInterrupted ()); thread.interrupt (); TimeUnit, MILLISECONDS sleep (2); System.out.printf ("Thread is interrupted?% s\ n", thread.isInterrupted ());}}
Because the interruptible method sleep is used in the run method, it will capture the interrupt signal and erase the interrupt identity, so the execution result of the program will be false, and the program output is as follows:
Thread is interrupted? FalseI am be interrupted? FalseThread is interrupted? False
In fact, it is not difficult to understand that after the interrupt signal is captured by the interruptible method, in order not to affect the execution of other methods in the thread, it is a reasonable design to reset the interrupt identity of the thread.
Interrupted
Interrupted is a static method, although it is also used to determine whether the current thread is interrupted, it is still very different from the member method islnterrupted. Calling this method will directly erase the interrupt identity of the thread. It should be noted that if the current thread is interrupted, the first call to the interrupted method will return true and immediately erase the interrupt identity. The second call, including subsequent calls, will always return false, unless the thread is interrupted again during that time. Here's a simple example to verify our claim:
Package com.wangwenjun.concurrent.chapter03;import java.util.concurrent.TimeUnit;public class Threadinterruptedpublic static void main (String [] args) throws InterruptedException {Thread thread = new Thread () {@ Overridepublic void run () {while (true) {System.out.printIn (Thread.interrupted ());}}; thread.setDaemon (true); thread.start (); / / shortly block make sure the thread is started.TimeUnit, MILLISECONDS.sleep (2); thread.interrupt ();}}
Similarly, because we do not want to be affected by interruptible methods such as sleep, there is no any short hibernation in Thread's run method, so running the above program will produce a lot of output, but we will find that the content shown below is sufficient as an explanation for this method.
Falsefalsetruefalsefalse
A true is found in many false enclosures, that is, the interrupted method determines that it is interrupted, erases the interrupt flag immediately, and returns true only this time, followed by false.
Considerations for interrupt
When you open the source code of Thread, it is not difficult to find that both the islnterrupted method and the interrupted method call the same local method:
Private native boolean islnterrupted (boolean Clearlnterrupted)
The parameter Clearlnterrupted is mainly used to control whether to erase the identity of the thread interrupt.
This parameter in the source code of the islnterrupted method is false, which means that you do not want to erase:
Public boolean islnterrupted () {return islnterrupted (false);}
In the interrupted static method, this parameter is true, indicating that you want to erase:
Public static boolean interrupted () {return currentThread () .islnterrupted (true);}
After learning the interrupt method in more detail, think about the question: if a thread is interrupted before it has an interruptible method, it will then execute an interruptible method, such as sleep. Let's answer this question through a simple experiment:
Public static void main (String!] Args) {/ / ① determines whether the current thread has been interrupted System.out.printin ("Main thread is interrupted?" + Thread.interrupted ()); / / ② interrupts the current thread Thread.currentThread (). Interrupt (); / / ③ determines whether the current thread has been interrupted System.out.printin ("Main thread is interrupted?" + Thread.currentThread (). Islnterrupted (); try {/ / ④ current thread executes interruptible method TimeUnit.MINUTES.sleep (1);} catch (InterruptedException e) {/ / ⑤ captures interrupt signal System.out.printin ("I will be interrupted still.");}}
By running the above program, you will find that if a thread sets the interrupt flag, then the next interruptible method will be interrupted immediately, so the signal capture part of the code of commenting ⑤ will be executed. Please note the difference between the method of judging thread interruption in annotating ① and annotating ③. I also hope that readers will think about why they do so in combination with the contents of this section.
Thread join
Thread's join method is also a very important method, using its features can achieve a lot of powerful functions, like sleep-it is also an interruptible method, that is, if other threads perform the interrupt operation on the current thread, it will also capture the interrupt signal and erase the thread's interrupt identification. Thread's API provides us with three different join methods, as follows.
□ public final void join () throws InterruptedException □ public final synchronized void join (long millis, int nanos) throws InterruptedException □ public final synchronized void join (long millis) throws InterruptedException
In this section, the author will introduce the join method in detail and how to use the join method in practical applications.
Detailed explanation of thread join method
Join a thread A will cause the current thread B to wait until thread An ends its life cycle or reaches a given time, during which time thread B is in BLOCKED instead of thread A. here is a simple example to explain the basic usage of the join method:
Package com.wangwenjun.concurrent.chapter03;import java.util.List;import java.util.concurrent.TimeUnit;import java.util.stream.IntStream;import static java.util.stream.Collectors.toList;public class Threadjoin {public static void main (String [] args) throws InterruptedException {/ / ① defines two threads and saves them in threads List threads = IntStream.range (1,3) .mapToObj (Threadjoin::create) .threads (toList ()); / / ② starts the two threads threads. ForEach (Thread::start) / / ③ executes the join method for (Thread thread: threads) {thread.join ();} / / ④ main thread loop output for (int I = 0; I) of these two threads
< 10; i++)System.out.printin(Thread.currentThread().getName() + "+ i); shortSleep();//构造一个简单的线程,每个线程只是简单的循环输出private static Thread create(int seq){return new Thread(() ->{for (int I = 0; I)
< 10; i++){System・ out・ printin(Thread.currentThread()・ getName() + "#" + i); shortSleep();}}, String.valueOf(seq));}private static void shortSleep(){try{TimeUnit, SECONDS.sleep(1);} catch (InterruptedException e){e.printStackTrace();}}} 上面的代码结合Java 8的语法,创建了两个线程,分别启动,并且调用了每个线程的 join方法(注意:join方法是被主线程调用的,因此在第一个线程还没有结束生命周期的时 后,第二个线程的join不会得到执行,但是此时,第二个线程也已经启动了),运行上面的 程序,你会发现线程一和线程二会交替地输出直到它们结束生命周期,main线程的循环才 会开始运行,程序输岀如下: 2#81#82#91#9main#0main#lmain#2main#3 如果你将注释③下面的join全部注释掉,那么三个线程将会交替地输出,程序输出如下: main#22#21#2main#31#32#3 main#4 join方法会使当前线程永远地等待下去,直到期间被另外的线程中断,或者join的线 程执行结束,当然你也可以使用join的另外两个重载方法,指定毫秒数,在指定的时间到 达之后,当前线程也会退出阻塞。同样思考一个问题,如果一个线程已经结束了生命周期, 那么调用它的join方法的当前线程会被阻塞吗? join方法结合实战 本节我们将结合一个实际的案例,来看一下join方法的应用场景,假设你有一个APP, 主要用于查询航班信息,你的APP是没有这些实时数据的,当用户发起查询请求时,你需 要到各大航空公司的接口获取信息,最后统一整理加工返回到APP客户端,如图3-1所示, 当然JDK自带了很多高级工具,比如CountDownLatch和CyclicBarrier等都可以完成类似 的功能,但是仅就我们目前所学的知识,使用join方法即可完成下面的功能。 该例子是典型的串行任务局部并行化处理,用户在APP客户端输入出发地"北京"和 目的地"上海",服务器接收到这个请求之后,先来验证用户的信息,然后到各大航空公司 的接口查询信息,最后经过整理加工返回给客户端,每一个航空公司的接口不会都一样, 获取的数据格式也不一样,查询的速度也存在着差异,如果再跟航空公司进行串行化交互 (逐个地查询),很明显客户端需要等待很长的时间,这样的话,用户体验就会非常差。如果 我们将每一个航空公司的查询都交给一个线程去工作,然后在它们结束工作之后统一对数 据进行整理,这样就可以极大地节约时间,从而提高用户体验效果。 代码清单3-1 查询接口 FightQuery package com.wangwenjun.concurrent.chapter03;import j ava.util.List;public interface FightQuery{List get();} 在代码清单3-1中,FightQuery提供了一个返回方法,写到这里大家应该注意到了,不 管是Thread的run方法,还是Runnable接口,都是void返回类型,如果你想通过某个线 程的运行得到结果,就需要自己定义一个返回的接口。 查询Fight的task,其实就是一个线程的子类,主要用于到各大航空公司获取数据,示 例代码如下: package com.wangwenjun,concurrent.chapter03;import java.util.ArrayList;import j ava.util.List;import j ava.util.concurrent.ThreadLocalRandom;import java.util.concurrent.TimeUnit;public class FightQueryTask extends Thread implements FightQuery public FightQueryTask(String airline, String origin, String destination)super("[">The interface is defined, and there are threads for querying flight data, so let's implement the flight query from SH (Shanghai) to Beijing (BJ). The sample code is as follows: package com.wangwenjun.concurrent.chapter0 3 * import java.util.ArrayList;import java.util.Arrays;import java.util.List;import static java.util.stream.Collectors.toList;public class FightQueryExample {/ / the major airlines that ① cooperates with private static List fightCompany = Arrays.asList ("CSA", "CEA", "HNA") Public static void main (String [] args) {List results = search ("SH", "BJ"); System.out.printin ("= result="); results, forEach (System ·out:: printin);} private static List search (String original, String dest) {final List result= new ArrayList (); / / ② creates a list of threads for querying flight information List tasks = fightCompany.stream (). Map (f-> createSearchTask (f, original, dest)) .flights (toList ()) / / ③ starts these threads tasks, forEach (Thread::start) respectively; "④ calls the join method of each thread respectively, blocking the current thread tasks.forEach (t-> tryt.join ();} catch (InterruptedException e) {}})) / / ⑤ before that, the current thread blocks, gets the results of each query thread, and adds tasks.stream () .map (FightQuery::get) .forEach (result::addAll) to result; return result;} FightQueryTask createSearchTask (fight,original, String dest) return new FightQueryTask (fight,original, dest) } the key points of the above code have been explained very clearly through comments. After receiving the search request, the main thread gives it to several query threads to work separately, and finally uniformly summarizes the flight data obtained by each thread. Since the query time of each airline may be different, a random value is used to reflect the different query speed and returned to the client (print to the console). The output of the execution result of the program is as follows: [CSA]-query from SH to BJ [CEA]-query from SH to BJ [HNA]-query from SH to BJ The Fight: [HNA] list query The Fights [CSA] list query The Fight: [CEA] list query = result=: [CSA]-4 [CEA]-7 [HNA]-2 how to close a thread JDK has a Deprecated method stop, but there is a problem with this method, which is not recommended by JDK officials. It may be removed in later versions. According to the description of the official website, the lock of monitor may not be released when the thread is closed, so it is strongly recommended not to use this method to end the thread. This section will mainly introduce several ways to close the thread. Close\ 1 normally. The thread ends its life cycle ends normally, and after completing its mission, it exits normally. If the task in the thread takes a short time, or the time is controllable, then let it end normally. \ 2. Capture the interrupt signal to close the thread We use new Thread to create a thread, which seems simple, but in fact, its derivative cost is relatively high, so it tends to perform a task in a thread, such as heartbeat check, constantly receiving network messages, and so on. When the system decides to exit, it can exit by interrupting the thread. The sample code is as follows: package com.wangwenjun.concurrent.chapter0 3 Import java.util.concurrent. TimeUnit;public class InterruptThreadExit {public static void main (String [] args) throws InterruptedException {Thread t = new Thread () {@ Overridepublic void run () {System.out.printin ("I will start work"); while (! islnterrupted ()) {/ / working.} System.out.printin ("I will be exiting.");}} T.start (); TimeUnit.MINUTES sleep (1); System.out.printin ("System will be shutdown."); t.interrupt ();}} the above code determines whether to exit by checking the identity of the thread interrupt, and if you execute an interruptible method in the thread, you can decide whether to exit by capturing the interrupt signal. @ Overridepublic void run () System.out.printin ("I will start work"); for (;;) / / working, tryTimeUnit.MILLISECONDS.sleep (l); catch (InterruptedException e) break;}} System.out.printin ("I will be exiting.");} the above code execution results will lead to the normal end of the thread. The program output is as follows: I will start workSystem will be shutdown.I will be exiting. \ 3. Using the volatile switch to control because the interrupt identity of the thread is likely to be erased, or because no interruptible methods are called in the logical unit, it is also a common practice to use the volatile-modified switch flag to close the thread, as follows: package com.wangwenjun.concurrent.chapter03;import java.util ·concurrent.TimeUnit; public class FlagThreadExitstatic class MyTask extends Threadprivate volatile boolean closed = false;@Override public void run () System.out.printIn ("I will start work") While (Iclosed & &! islnterrupted ()) / / running} System.out.printin ("I will be exiting."); public void close () {this.closed = true;this, interrupt ();}? public static void main (String [] args) throws InterruptedException {MyTask t = new MyTask (); t.start (); TimeUnit MINUTES.sleep (1); System.out.printIn ("System will be shutdown."); t.close () }} the above example defines a closed switch variable and is modified with volatile (the volatile key will be explained in great detail in part 3 of this book, the volatile keyword in Java is a revolutionary keyword, very important, it is the basis of Java atomic variables and concurrent packages) running the above program can also close the thread. Exception exit is not allowed to throw a checked exception in the execution unit of a thread, regardless of the run method in Thread or the run method in Runnable. If the thread needs to catch the checked exception and determine whether it is necessary to run, then the checked exception can be encapsulated as a unchecked exception (RuntimeException) to end the thread's life cycle. At this point, I believe you have a deeper understanding of "what is multithreaded source code", you might as well come to the actual operation of it! Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.