In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
Editor to share with you how to ensure thread sequence execution in Java, I believe most people do not know much about it, so share this article for your reference, I hope you can learn a lot after reading this article, let's go to know it!
As long as we know too much about multiple threads, we know that the order in which threads start is different from the order in which they are executed. If you just create three threads and then execute them, the final order of execution is unexpected. This is because after the thread is created, the start time of thread execution depends on when the CPU allocates time slices, and the thread can be seen as an asynchronous operation relative to the main thread.
Public class FIFOThreadExample {public synchronized static void foo (String name) {System.out.print (name);} public static void main (String [] args) {Thread thread1 = new Thread (()-> foo ("A")); Thread thread2 = new Thread (()-> foo ("B")); Thread thread3 = new Thread (()-> foo ("C")); thread1.start () Thread2.start (); thread3.start ();}}
Output: ACB/ABC/CBA...
So how do we ensure that threads are executed sequentially?
How to ensure the sequential execution of threads? 1. Using Thread.join () to implement
The purpose of Thread.join () is to make the parent thread wait for the child thread to finish before continuing to run. Taking the above example as an example, the thread in which the main () method is located is the parent thread, in which we create three child threads, A _ dint B _ Department C. the execution of the child thread is asynchronous relative to the parent thread, and the sequence can not be guaranteed. After using the Thread.join () method on the child thread, we can make the parent thread wait until the end of the child thread, and then start executing the parent thread, so that the execution of the child thread is forced to become synchronous, and we can use the Thread.join () method to ensure the sequence of thread execution.
Public class FIFOThreadExample {public static void foo (String name) {System.out.print (name);} public static void main (String [] args) throws InterruptedException {Thread thread1 = new Thread (()-> foo ("A")); Thread thread2 = new Thread (()-> foo ("B")); Thread thread3 = new Thread (()-> foo ("C")); thread1.start () Thread1.join (); thread2.start (); thread2.join (); thread3.start ();}}
Output: ABC
two。 Using a single-thread thread pool to implement
Another way to ensure that threads execute sequentially is to use a single-threaded thread pool in which there is only one thread, and accordingly, internal threads execute in the order in which they are added.
Import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class FIFOThreadExample {public static void foo (String name) {System.out.print (name);} public static void main (String [] args) throws InterruptedException {Thread thread1 = new Thread (()-> foo ("A")); Thread thread2 = new Thread (()-> foo ("B")) Thread thread3 = new Thread (()-> foo ("C")); ExecutorService executor = Executors.newSingleThreadExecutor (); executor.submit (thread1); executor.submit (thread2); executor.submit (thread3); executor.shutdown ();}}
Output: ABC
3. Semaphore implementation modified with volatile keyword
The above two ideas are to ensure the execution order of the threads and let the threads execute in a certain order. The third idea here is that threads can run out of order, but the execution results are executed sequentially.
As you can imagine, all three threads are created and start (), and the three threads may execute the run () method at any time. So in order to ensure the sequence of run () execution, we definitely need a semaphore to let the thread know whether the logical code can be executed at any time.
In addition, because the three threads are independent, the change in this semaphore must be transparent to other threads, so the volatile keyword is also required.
Public class TicketExample2 {/ / semaphore static volatile int ticket = 1; / thread sleep time public final static int SLEEP_TIME = 1 Public static void foo (int name) {/ / because the execution order of threads is unpredictable, each thread needs to spin while (true) {if (ticket = = name) {try {Thread.sleep (SLEEP_TIME) / / print for 3 times per thread cycle (int I = 0; I
< 3; i++) { System.out.println(name + " " + i); } } catch (InterruptedException e) { e.printStackTrace(); } //信号量变更 ticket = name%3+1; return; } } } public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(() ->Foo (1)); Thread thread2 = new Thread (()-> foo (2)); Thread thread3 = new Thread (()-> foo (3)); thread1.start (); thread2.start (); thread3.start ();}}
Execution result:
1 0
1 1
1 2
2 0
2 1
2 2
3 0
3 1
3 2
4. Using Lock and semaphores to implement
The idea of this method is the same as the third method, regardless of the order in which the threads execute, but in some ways to control the order in which the threads execute the business logic. Here we also use an atomic type semaphore ticket, of course you can not use atomic types, here I am just to ensure thread safety of self-increment operations. Then we used a reentrant lock ReentrantLock. It is used to lock a method, start executing business logic when a thread gets the lock and identify the correct bit, and wake up the next thread after execution.
Here we do not need to use while for spin operations, because Lock allows us to wake up specified threads, so change to if to achieve sequential execution.
Public class TicketExample3 {/ / semaphore AtomicInteger ticket = new AtomicInteger (1); public Lock lock = new ReentrantLock (); private Condition condition1 = lock.newCondition (); private Condition condition2 = lock.newCondition (); private Condition condition3 = lock.newCondition (); private Condition [] conditions = {condition1, condition2, condition3}; public void foo (int name) {try {lock.lock () / / because the execution order of threads is unpredictable, each thread needs to spin System.out.println ("thread" + name + "start execution") If (ticket.get ()! = name) {try {System.out.println ("current identifier bit is" + ticket.get () + ", thread" + name + "start waiting"); / / start waiting for conditions [name-1] .await () System.out.println ("Thread" + name + "Wake up");} catch (InterruptedException e) {e.printStackTrace ();}} System.out.println (name); ticket.getAndIncrement () If (ticket.get () > 3) {ticket.set (1);} / / finish execution, wake up next time. 1Wake up 2Jing 2 Wake up 3 conditions [name% 3] .signal ();} finally {/ / must release lock lock.unlock ();}} public static void main (String [] args) throws InterruptedException {TicketExample3 example = new TicketExample3 (); Thread T1 = new Thread (()-> {example.foo (1);}) Thread T2 = new Thread (()-> {example.foo (2);}); Thread T3 = new Thread (()-> {example.foo (3);}); t1.start (); t2.start (); t3.start ();}}
Output result:
Thread 2 starts execution
The current identification bit is 1 and thread 2 starts waiting
Thread 1 starts execution
one
Thread 3 starts execution
The current identification bit is 2, and thread 3 starts waiting.
Thread 2 is awakened
two
Thread 3 is awakened
three
The above execution result is not unique, but it can be guaranteed that the printing order must be 123.
The above is all the contents of the article "how to ensure thread sequential execution in Java". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!
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.