Related free learning recommendations: java basic tutorial
Commonly used auxiliary classes
1.CountDownLatch
1.2.Example: Monitor locks the door Problem
Problem description: Suppose there are 7 students studying in the evening. The key is in the hands of the monitor, and he is responsible for locking the door. The monitor must wait until everyone is gone before he can turn off the lights and lock the door. The order of these six students is disordered, and I don’t know when they left. Each of the six students took their own self-study classes, with no interaction in between. Suppose the 6 students are ordinary threads and the monitor is the main thread. How can we make the main thread wait for a bunch of threads to finish running before the main thread can finish running?public class CountDownLatchDemo { public static void main(String[] args) { // TODO Auto-generated method stub for(int i=1;i{ System.out.println(Thread.currentThread().getName()+"\t离开教室"); },String.valueOf(i)).start(); } System.out.println(Thread.currentThread().getName()+"\t班长关门走人"); }}Screenshot of running results
Finally, there are three people locked in the teacher. This may cause an accident, so it is definitely not possible.
1.2. Introduction to the CountDownLatch class:
1.2.1 CountDownLatch concept
CountDownLatch is a synchronization tool class used to coordinate synchronization between multiple threads, or to communicate between threads (rather than serving as a mutual exclusion).
CountDownLatch enables a thread to wait for other threads to complete their work before continuing to execute . Use a counter to implement. The initial value of the counter is the number of threads. When each thread completes its task, the counter value is decremented by one. When the counter value is 0, it means that all threads have completed some tasks, and then the threads waiting on CountDownLatch can resume executing the next tasks .
CountDownLatch description: count count, count down, start Latch1.2.3 Usage of CountDownLatch
A certain thread starts at the beginning Wait for n threads to complete execution before running. Initialize the CountDownLatch counter to new CountDownLatch(n). Whenever a task thread completes execution, the counter is decremented by 1 countdownLatch.countDown(). When the counter value becomes 0, the thread await() on CountDownLatch will be awakened. A typical application scenario is that when starting a service, the main thread needs to wait for multiple components to be loaded before continuing execution. CountDownLatch underlying constructor source code
public CountDownLatch(int count) { if (count <p>1.3.CountDownLatch case: <strong></strong></p><pre class="brush:php;toolbar:false">public static void main(String[] args) throws InterruptedException { //6个同学正在上自习,每个人就有一个1计数器,走1个数字减1,main线程启动,必须要等计时器从6变成0,才能开始。 CountDownLatch countDownLatch=new CountDownLatch(6); for(int i=1;i{ System.out.println(Thread.currentThread().getName()+"\t离开教室"); countDownLatch.countDown(); //计算减少一个 },String.valueOf(i)).start(); } countDownLatch.await(); //班长前面需要被阻塞 System.out.println(Thread.currentThread().getName()+"\t班长关门走人"); }Run result screenshot
Here We don’t know when everyone will leave, but we can guarantee that the squad leader will be the last to leave every time.
1.4. Principle summary
CountDownLatch mainly has two methods. When one or more threads call the await method, these threads will be blocked. Calling the countDown method by other threads will decrement the counter by 1 (the thread calling the countDown method will not be blocked)
When the counter value becomes 0, the thread blocked by the await method will be awakened and execution will continue.
2.CyclicBarrier
2.1. Introduction to CyclicBarrier
cyclic cycle, barrier barrier. From the literal meaning, the Chinese meaning of this class is "circulating fence". It roughly means a recyclable barrier.
Its function is to make all threads wait for completion before continuing to the next step. The above example of the monitor closing the door is to do a countdown, here it is the other way around, to do addition, and start when the number is reached.
For example, when everyone is here, start the meeting again. , for example, just like in life, we will invite colleagues to go to a meeting. Some colleagues may arrive early and some colleagues may arrive late. However, the meeting stipulates that we must wait until everyone has arrived before we can officially Have a meeting. The colleagues here are the threads, and the meeting is the CyclicBarrier.
public CyclicBarrier(int parties)public CyclicBarrier(int parties, Runnable barrierAction)Analysis:
parties is the number of participating threads The second construction method has a Runnable parameter, which means the last one To reach the task to be done by the thread
2.2. Case: Collect 7 Dragon Balls to Summon the Dragon
public static void main(String[] args) { // TODO Auto-generated method stub CyclicBarrier cyclicBarrier=new CyclicBarrier(7,()->{System.out.println("召唤神龙");}); for(int i=1;i{ System.out.println(Thread.currentThread().getName()+"\t收集到第"+tempInt+"颗龙珠"); try { //某个线程收集到了龙珠只能先等着,等龙珠收齐了才能召唤神龙 cyclicBarrier.await(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } },String.valueOf(i)).start();; } }
截图
3.Semophore
3.1.Semophore简介
前面讨论的问题都是多对一的问题,我们现在可以讨论多对多的问题了。
假设有7个兄弟开车上班,而现在只有4个车位。7部车并列开进4个车位,每个车停了多长时间未知,资源被占用完了。假设有一个车只停了2s,那么它走了,外面的车又可以进来了。走一个进一个,最后全部都可以进去。而semophore就是控制多线程的并发策略。
简单理解来说,Semaphore:信号量主要用于两个目的:一个是用于多个共享资源的互斥使用;另一个用于并发线程数量的控制。
Semaphore类有两个重要方法
1、semaphore.acquire();
请求一个信号量,这时候信号量个数-1,当减少到0的时候,下一次acquire不会再执行,只有当执行一个release()的时候,信号量不为0的时候才可以继续执行acquire
2、semaphore.release();
释放一个信号量,这时候信号量个数+1,
3.2.抢车位问题
public static void main(String[] args) { //模拟6部车抢3个空车位 Semaphore semaphore=new Semaphore(3);//模拟资源类,有3个空车位 for(int i=1;i{ try { //谁先抢到了,谁就占一个车位,并且要把semaphore中的资源数减1 semaphore.acquire(); System.out.println(Thread.currentThread().getName()+"\t抢占到了车位"); TimeUnit.SECONDS.sleep(3); System.out.println(Thread.currentThread().getName()+"\t离开了车位"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ //释放车位 semaphore.release(); } },String.valueOf(i)).start(); } }
运行结果截图:
3.3.原理总结
在信号量上我们定义两种操作:
acquire(获取)当一个线程调用acquire操作时,它要么通过成功获取信号量(信号量减1),要么一直等待下去,直到有线程释放信号量,或超时。
release(释放)实际上会将信号量的值加1,然后唤醒等待的线程。
信号量主要用于两个目的:一个是用于多个共享资源的互斥使用;另一个用于并发线程数量的控制
如果把资源数从3变成1了,此时就等价于synchronized。
The above is the detailed content of Java concurrent programming, introducing commonly used auxiliary classes. For more information, please follow other related articles on the PHP Chinese website!