Multithreading 001, multithreading

Source: Internet
Author: User

Multithreading 001, multithreading

In many cases, we expect to implement this function: start some sub-threads in the main thread, and wait until all sub-threads finish executing, the main thread continues to execute. For example, the boss assigns tasks and many workers start to work. After all workers finish their work, the boss checks the jobs.

Solution Analysis:

Implement through join

The first method is to directly call the join method of the thread in Java API and wait for the thread to terminate.

Every worker is a thread, and its run method is the implementation of work. Each worker is distinguished by name. The specific code is as follows:

Package howe. demo. thread. join; import java. util. random; import java. util. concurrent. timeUnit;/*** @ author liuxinghao * @ version 1.0 Created on April 9, September 12, 2014 */public class Worker extends Thread {private String workerName; public Worker (String workerName) {this. workerName = workerName;}/*** @ see java. lang. thread # run () */@ Override public void run () {System. out. println (this. workerName + "working... "); Try {TimeUnit. SECONDS. sleep (new Random (). nextInt (10);} catch (InterruptedException e) {} System. out. println (this. workerName + "finished! ");} Public String getWorkerName () {return workerName ;}}

The boss recruited the workers, arranged for the workers to work, waited for the workers to finish their work, and checked the workers' work achievements (capitalists ...), The Code is as follows:

Package howe. demo. thread. join; import java. util. list;/*** @ author liuxinghao * @ version 1.0 Created on April 9, September 12, 2014 */public class Boss {private List <Worker> workers; public Boss (List <Worker> workers) {System. out. println ("the boss recruits workers. "); This. workers = workers;} public void work () {System. out. println ("the boss started to arrange work for workers... "); for (Worker worker: workers) {System. out. println ("boss Arrangement" + worker. getWorkerName () + "job"); worker. start ();} System. out. println ("the boss has finished his work... "); System. out. println ("the boss is waiting for all the workers to finish their work ...... "); for (Worker w: workers) {try {w. join ();} catch (InterruptedException e) {}} System. out. println ("the worker is finished, and the boss checks it! ");}}

Now write the main method for testing:

Package howe. demo. thread. join; import java. util. arrayList; import java. util. list;/*** @ author liuxinghao * @ version 1.0 Created on September 12, 2014 */public class JoinDemo {public static void main (String [] args) {Worker w1 = new Worker ("John"); Worker w2 = new Worker ("Lee"); Worker w3 = new Worker ("Wang Wu "); list <Worker> workers = new ArrayList <Worker> (); workers. add (w1); workers. add (w2); workers. add (w3); Boss boss = new Boss (workers); boss. work (); System. out. println ("main method ended ");}}

The execution result is:

The boss recruits workers. The boss started arranging work for workers... the boss arranged Michael's work. The boss arranged Michael's work. Michael was working... the boss arranged for Wang Wu's work. Li Si was working... the boss arranged the work to end... the boss is waiting for all the workers to finish their work ...... wang Wu is working... wang Wu finished his work! Zhang San is finished! Li Si finished his work! After all the workers were finished, the boss began to check! The main method ends.
Implement through counters

The second method can implement a counter to count the total number of sub-threads and the number of unfinished threads. When the number of unfinished threads is about 0, the main thread waits. When the number of unfinished threads is equal to 0, the main thread continues execution.

Of course, since we now think of this method, the Java API team will also think that JDK 1.5 provides CountDownLatch for implementing the above method.

Modify the preceding methods:

Package howe. demo. thread. cdl; import java. util. random; import java. util. concurrent. countDownLatch; import java. util. concurrent. timeUnit;/*** @ author liuxinghao * @ version 1.0 Created on 2014-9-12 */public class Worker extends Thread {private CountDownLatch downLatch; private String workerName; public Worker (CountDownLatch downLatch, string workerName) {this. downLatch = downLatch; this. workerName = WorkerName;} public void run () {System. out. println (this. workerName + "working... "); try {TimeUnit. SECONDS. sleep (new Random (). nextInt (10);} catch (InterruptedException ie) {} System. out. println (this. workerName + "finished! "); This. downLatch. countDown ();} public String getWorkerName () {return workerName ;}}

Latch. countDown () is used to reduce the number of subthreads by one after the sub-thread execution ends.

The boss class must also make corresponding changes:

Package howe. demo. thread. cdl; import java. util. list; import java. util. concurrent. countDownLatch;/*** @ author liuxinghao * @ version 1.0 Created on 2014-9-12 */public class Boss {private List <Worker> workers; private CountDownLatch downLatch; public Boss (List <Worker> workers, CountDownLatch downLatch) {this. workers = workers; this. downLatch = downLatch;} public void work () {System. out. println ("opened by the boss Start arranging work for workers... "); for (Worker worker: workers) {System. out. println ("boss Arrangement" + worker. getWorkerName () + "job"); worker. start ();} System. out. println ("the boss has finished his work... "); System. out. println ("the boss is waiting for all the workers to finish their work ...... "); try {this. downLatch. await ();} catch (InterruptedException e) {} System. out. println ("the worker is finished, and the boss checks it! ");}}

Latch. await () is waiting for the end of the sub-thread.

Compile the main method for verification:

Package howe. demo. thread. cdl; import java. util. arrayList; import java. util. list; import java. util. concurrent. countDownLatch;/*** @ author liuxinghao * @ version 1.0 Created on September 15, 2014 */public class CountDownLatchDemo {public static void main (String [] args) {CountDownLatch latch = new CountDownLatch (3); Worker w1 = new Worker (latch, "Zhang San"); Worker w2 = new Worker (latch, "Li Si "); worker w3 = new Worker (latch, ""); List <Worker> workers = new ArrayList <Worker> (); workers. add (w1); workers. add (w2); workers. add (w3); Boss boss = new Boss (workers, latch); boss. work (); System. out. println ("main method ended ");}}

The execution result is:

The boss started arranging work for workers... the boss arranged Michael's work. The boss arranged Michael's work. Michael was working... the boss arranged for Wang Wu's work. Li Si was working... the boss arranged the work to end... the boss is waiting for all the workers to finish their work ...... wang Wu is working... wang Wu finished his work! Li Si finished his work! Zhang San is finished! After all the workers were finished, the boss began to check! The main method ends.
Implementation Using Circular barrier

There is another implementation, which does not block the main thread, but listens to all sub-threads to end. The code used in the preceding scenario is as follows:

WORKER:

Package howe. demo. thread. cyclicbarrier; import java. util. random; import java. util. concurrent. brokenBarrierException; import java. util. concurrent. cyclicBarrier; import java. util. concurrent. timeUnit;/*** @ author liuxinghao * @ version 1.0 Created on April 9, September 12, 2014 */public class Worker extends Thread {private String workerName; private javasicbarrier barrier; public Worker (String workerName, javasicbarrier ba Rrier) {this. workerName = workerName; this. barrier = barrier;} @ Override public void run () {System. out. println (this. workerName + "working... "); try {TimeUnit. SECONDS. sleep (new Random (). nextInt (10);} catch (InterruptedException e) {} System. out. println (this. workerName + "finished! "); Try {barrier. await ();} catch (InterruptedException e) {e. printStackTrace ();} catch (BrokenBarrierException e) {e. printStackTrace () ;}} public String getWorkerName () {return workerName ;}}

Boss class:

Package howe. demo. thread. cyclicbarrier; import java. util. list;/*** @ author liuxinghao * @ version 1.0 Created on */public class Boss {private List <Worker> workers; public Boss (List <Worker> workers) {this. workers = workers;} public void work () {System. out. println ("the boss started to arrange work for workers... "); for (Worker worker: workers) {System. out. println ("boss Arrangement" + worker. getWorkerName () + "job"); worker. start ();} System. out. println ("the boss has finished his work... "); System. out. println ("the boss is waiting for all the workers to finish their work ...... ");}}

Main method test:

Package howe. demo. thread. cyclicbarrier; import java. util. arrayList; import java. util. list; import java. util. concurrent. cyclicBarrier;/*** @ author liuxinghao * @ version 1.0 Created on April 9, September 15, 2014 */public class extends icbarrierdemo {public static void main (String [] args) {javasicbarrier barrier = new javasicbarrier (3, new Runnable () {@ Override public void run () {System. out. println ("the worker is finished, and the boss checks it! ") ;}}); Worker w1 = new Worker (" Zhang San ", barrier); Worker w2 = new Worker (" Li Si ", barrier ); worker w3 = new Worker ("Wang Wu", barrier); List <Worker> workers = new ArrayList <Worker> (); workers. add (w1); workers. add (w2); workers. add (w3); Boss boss = new Boss (workers); boss. work (); System. out. println ("main method ended ");}}

The execution result is:

The boss started arranging work for workers... the boss arranged Michael's work. The boss arranged Michael's work. Michael was working... the boss arranged for Wang Wu's work. Li Si was working... the boss arranged the work to end... the boss is waiting for all the workers to finish their work ...... wang Wu is working... the main method is complete! Wang Wu finished his work! Zhang San is finished! After all the workers were finished, the boss began to check!

The result analysis shows that after the work method of the boss object is executed, the main method is executed. (Here, "the boss is waiting for all the workers to finish their work ...... "After printing," Wang Wu is working... ", and then the" main method ends ", because the cpu is preemptible, or even has a certain probability that" main method ends "will be printed at the end .)

Assuming that we have such a function, we need to write some records to the database in batches and record the time used for this operation, but we do not want to affect other operations (that is, we do not want to block the main thread ), at this time, CyclicBarrier will be used.


Mutex is used to share code or resources under multiple threads. What does Mutex mean?

The use of mutex objects is basically the same as that of Event. The difference is that Mutex is called a global Mutex object, which can be used not only in multiple threads, but also in multiple processes. Mutex is a named object. All Mutex files created with the same name are regarded as the same object.
Both Mutex and Event can be used for synchronization and Mutex. Because of its own characteristics, many resources require only one thread to access at the same time, such as a data structure such as vector. At the same time, there are two threads to perform the insert operation, and the data will go wrong. The same is true for the code, some code itself is not allowed to enter in the middle of multiple threads at the same time. At this time, Mutex or Event can be used for mutual exclusion.
The specific method is to create a Mutex or Event with the initial value True (Set) (ManualReset parameter is FALSE), and then WaitForSingleObject is the first time you want to access the corresponding resource, after Wait is successful, Event or Mutex changes to the False (Unset) state, and other threads cannot enter the State. After the use is complete, SetEvent restores the Mutex or Event to the Set state, let other waiting threads enter.
CriticalSection and other modules also use Event or Mutex internally to achieve mutual exclusion. Note that you need to use an independent Mutex or Event for each Mutex resource or code.

Java multi-thread access

Your design is just a singleton mode, but there are also problems
Public static Singleton getInstance (){
If (singleton = null)
Return new Singleton (); // never assigned a value to singleton.
Else
Return singleton;
}
You can change return singleton = new Singleton ();
There is also a problem -- (Something happened yesterday, not finished !) If a thread determines that singleton is null and has not been assigned a value, it will be paused, and the other thread will run here to assign a value to singleton, the value is assigned again when the previous thread starts execution. A synchronized (this) Lock should be added! It is a little complicated. You can define the value of singleton to getInstance and directly return this value.
I personally think that the multi-processor is scheduled by the operating system. We don't have to worry about it. All programs run on the Java Virtual Machine, we only care about virtual machines.
If you are running on multiple servers, you need to synchronize multiple VMS.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.