Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to start and terminate threads in Java

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces how to start and terminate threads in Java, the content is very detailed, interested friends can refer to, hope to be helpful to you.

In Java, we start a thread by calling the start () method in the Thread class, and automatically terminate when the thread finishes processing the logic in the run () method. But before calling the start () method, we need to build a Thread object. Usually we use the constructor of the Thread class directly to create a thread object. The Thread constructor is defined as follows:

Public Thread () {init (null, null, "Thread-" + nextThreadNum (), 0);} public Thread (Runnable target) {init (null, target, "Thread-" + nextThreadNum (), 0);} Thread (Runnable target, AccessControlContext acc) {init (null, target, "Thread-" + nextThreadNum (), 0, acc, false);} public Thread (ThreadGroup group, Runnable target) {init (group, target, "Thread-" + nextThreadNum (), 0) } public Thread (String name) {init (null, null, name, 0);} public Thread (ThreadGroup group, String name) {init (group, null, name, 0);} public Thread (Runnable target, String name) {init (null, target, name, 0);} public Thread (ThreadGroup group, Runnable target, String name) {init (group, target, name, 0) } public Thread (ThreadGroup group, Runnable target, String name, long stackSize) {init (group, target, name, stackSize);}

We can see that there are so many constructors defined in the Thread class, but these constructors call the init () method to complete the construction of the Thread object, and the init method is defined as follows:

Private void init (ThreadGroup g, Runnable target, String name, long stackSize) {init (g, target, name, stackSize, null, true) } / * @ param g thread group * @ param target calls the object of the run method * @ param name to create a new thread name * @ param stackSize when the stack size stackSize required to build a new thread is 0 Indicates whether to ignore this parameter * @ param acc context * @ param inheritThreadLocals inherits thread-locals * / private void init (ThreadGroup g, Runnable target, String name,long stackSize, AccessControlContext acc,boolean inheritThreadLocals) {if (name = = null) {throw new NullPointerException ("name cannot be null") } this.name = name; / / the parent thread of the build thread is the currently running thread Thread parent = currentThread (); SecurityManager security = System.getSecurityManager (); if (g = = null) {if (security! = null) {g = security.getThreadGroup () } / / if the thread group is empty, try to use the thread group if of the parent thread (g = = null) {g = parent.getThreadGroup ();}} / / Security check g.checkAccess (); if (security! = null) {if (isCCLOverridden (getClass () {security.checkPermission (SUBCLASS_IMPLEMENTATION_PERMISSION) }} / / increase the number of unstarted threads in the thread group g.addUnstarted (); this.group = g; / inherit the Daemon attribute of the parent thread this.daemon = parent.isDaemon (); / / inherit the priority of the parent thread this.priority = parent.getPriority () / / build an appropriate classloader if (security = = null | | isCCLOverridden (parent.getClass () this.contextClassLoader = parent.getContextClassLoader (); else this.contextClassLoader = parent.contextClassLoader; this.inheritedAccessControlContext = acc! = null? Acc: AccessController.getContext (); this.target = target; setPriority (priority); if (inheritThreadLocals & & parent.inheritableThreadLocals! = null) this.inheritableThreadLocals = ThreadLocal.createInheritedMap (parent.inheritableThreadLocals); this.stackSize = stackSize; / / assign an ID tid = nextThreadID () to the new thread;}

We can see from the init method that the thread daemon property, the thread's priority, the resource-loaded contextClassLoader, and the inheritable ThreadLocal are all inherited from the parent thread. The inheritance of the thread priority mentioned in the previous article is also verified here. After the init () method is executed, a thread object is built, which is stored in heap memory waiting for the call to the start () method to start. The definition of the start () method in the Thread class is as follows:

Public synchronized void start () {/ / build thread threadStatus defaults to 0 if (threadStatus! = 0) throw new IllegalThreadStateException (); / * notifies the thread group that the thread is about to start, adding the site to the thread group * / group.add (this); boolean started = false; try {start0 (); started = true } finally {try {if (! started) {/ / failed to start the thread, removing group.threadStartFailed (this) from the thread group;}} catch (Throwable ignore) {} private native void start0 () Void add (Thread t) {synchronized (this) {/ / if the thread has been destroyed, throw an exception if (destroyed) {throw new IllegalThreadStateException ();} / / Thread group is empty, initialize thread group if (threads = = null) {threads = new Thread [4] } else if (nthreads = = threads.length) {/ / the thread group is full, then the capacity is expanded by twice the original size threads = Arrays.copyOf (threads, nthreads * 2);} / / add threads to the thread group threads [nthreads] = t; / / the number of starting threads plus one nthreads++ / / minus one nUnstartedThreads--;}} void threadStartFailed (Thread t) {synchronized (this) {remove (t); nUnstartedThreads++;}} private void remove (Thread t) {synchronized (this) {if (destroyed) {return;} for (int I = 0; I < nthreads) If (threads [I] = = t) {System.arraycopy (threads, I + 1, threads, I,-- nthreads-I); threads [nthreads] = null; break;}

From the above source code, we can see that the start () method finally starts the thread by calling the local method start0 () method. So what does the local method start0 () do? it mainly completes the task of starting Thread in the virtual machine, executing the run () method overridden when building the Thread object, and modifying the value of threadStatus. From the source code of the start () method above, the start () method cannot be called repeatedly, and an IllegalThreadStateException exception is thrown when the start () method is called repeatedly. After talking about the start of the thread, let's talk about the termination of the thread.

Thread termination

When we look at the source code of the Thread class, we find that the Thread class provides stop (), suspend () and resume () methods for thread termination, pause and resumption. However, these methods are marked as obsolete in the Thread class, and developers are not recommended to use these methods. As for the reason, the children go to consult the data themselves, so LZ will not repeat it here. Since it is not officially recommended to terminate a thread in this way, what should we use instead? The alternative to the stop () method is to loop through a variable in the thread object's run method so that we can terminate the thread gracefully.

Public class ThreadOne extends Thread {private volatile boolean flag = true; @ Override public void run () {while (flag) {System.out.println (System.currentTimeMillis () / 1000 + "Thread is running"); try {TimeUnit.SECONDS.sleep (1);} catch (InterruptedException e) {e.printStackTrace () Public static void main (String [] args) throws InterruptedException {ThreadOne t = new ThreadOne (); t.start (); TimeUnit.SECONDS.sleep (5); t.flag = false;}} output:1554371306 thread is running 1554371307 thread is running 1554371308 thread is running 1554371309 thread is running 1554371310 thread is running

From the example above, we can see that the thread shuts down automatically after running for 5 seconds. This is because the main thread assigns a false value to the score value in the ThreadOne class after five seconds of sleep.

The alternative to the suspend () and resume () methods is to use the wait / notification mechanism. The wait / notify method is defined on top of the Object class, so any class can implement wait / notify. The wait / notification method is defined as follows:

/ / notify a waiting thread on the object to return from the wait () method, and return from the wait () method if you need to acquire the lock public final native void notify (); / / notify all waiting threads on the object, public final native void notifyAll (); / / timeout wait, the thread waits for timeout milliseconds on the object, and if the time exceeds, it directly returns public final native void wait (long timeout) throws InterruptedException / / timeout waiting, which can be controlled until the nanosecond public final void wait (long timeout, int nanos) throws InterruptedException// thread waits on the object until another thread calls the notify () or notifyAll () method public final void wait () throws InterruptedException {wait (0);}

An example of waiting / notification is as follows:

Public class NotifyAndWait {public static void main (String [] args) {Object lock = new Object (); WaitThread waitThread = new WaitThread (lock, "WaitThread"); waitThread.start (); NotifyThread notifyThread = new NotifyThread (lock, "NotifyThread"); notifyThread.start ();} class WaitThread extends Thread {private Object lock; public WaitThread (Object lock, String name) {super (name) This.lock = lock;} @ Override public void run () {synchronized (lock) {System.out.println (Thread.currentThread (). GetName () + "start running."); try {lock.wait ();} catch (InterruptedException e) {e.printStackTrace () } System.out.println (Thread.currentThread (). GetName () + "execution completed...");}} class NotifyThread extends Thread {private Object lock; public NotifyThread (Object lock, String name) {super (name); this.lock = lock } @ Override public void run () {synchronized (lock) {System.out.println (Thread.currentThread (). GetName () + "start running."); lock.notify (); System.out.println (Thread.currentThread (). GetName () + "execution complete.") } output:WaitThread start running. NotifyThread execution complete. WaitThread execution complete.

From the sample code above, we can see that when the WaitThread thread calls the start () method, when the wait () method is specified to put the release into the waiting queue, and then the NotifyThread acquires the lock, when the thread is notified that the notify () method is executed, it will notify the thread waiting on the lock, and when the NotifyThread thread finishes running, the WaitThread thread will resume execution. There are a few things to note when calling the wait () method and the notify () method:

You need to acquire the lock before calling the wait () or notify () methods.

When the wait () method is called, the thread has released the lock.

When the wait () method is called, the thread transitions from the running state to the WAITING state and puts the thread method into the waiting queue.

When the notify () / notifyAll () method is called, the thread does not release the lock immediately. It must release the lock after the thread has finished executing before the wait thread can acquire the lock and execute again.

On how to start and terminate threads in Java to share here, I hope the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.

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.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report