JUC的安全并发包机制
目录
1. Lock机制:明锁控制
2. 栅栏机制(CyclicBarrier)
3. 闭锁机制(CountDownLatch)
4. 信号量机制(Semaphore)
5. 无锁机制
1. Lock机制:明锁控制
Lock接口提供了比synchronized更灵活的锁机制,属于明锁(需要手动获取和释放锁)。与synchronized隐式锁不同,Lock需要显式地调用lock()和unlock()方法。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class LockDemo {private Lock lock = new ReentrantLock();private int count = 0;public void increment() {lock.lock(); // 手动获取锁try {count++;} finally {lock.unlock(); // 必须在finally中手动释放锁}}
}
2. 栅栏机制(CyclicBarrier)
栅栏机制允许一组线程相互等待,直到所有线程都到达某个屏障点,然后所有线程才会继续执行。CyclicBarrier可以重复使用,适用于分阶段的任务处理。
package com.demo5;import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;/*** * 研学,旅游公司包车,一个车做4个同学,坐满就发车; 总共有28个人,怎么控制和实现?**/public class Test {public static void main(String[] args) {// 设置屏障点CyclicBarrier cb = new CyclicBarrier(4, () -> {System.out.println("已经有4个同学了,就发车吧, 旅游车已经启动出发");});for (int i = 0; i < 28; i++) {Runnable r = () -> {System.out.println("学生来报道............");try {cb.await();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (BrokenBarrierException e) {// TODO Auto-generated catch blocke.printStackTrace();}};try {Thread.sleep(3000);} catch (InterruptedException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}new Thread(r).start();}}}
运行结果:
3. 闭锁机制(CountDownLatch)
闭锁是一种一次性使用的同步辅助工具,允许一个或多个线程等待其他线程完成操作。
package com.demo8;import java.util.concurrent.CountDownLatch;public class Test {public static void main(String[] args) {//闭锁,任务只能执行一次CountDownLatch cdl = new CountDownLatch(10);//10个人到了,一桌人开始吃饭,吃完就结束。for(int i=0;i<10;i++){Runnable r = ()->{System.out.println(Thread.currentThread().getName()+",来吃饭.....");cdl.countDown();//-1,一直到0};try {Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}new Thread(r).start();}try {cdl.await(); // 等待计数器归零,屏障点解除} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("我们开始欢乐的用餐");}}
运行结果:
4. 信号量机制(Semaphore)
信号量用于控制同时访问特定资源的线程数量,通过许可证机制实现资源池的访问控制。
package com.demo9;import java.util.Random;
import java.util.concurrent.Semaphore;public class Test {public static void main(String[] args) {Semaphore s = new Semaphore(3); // 允许3个线程同时访问for(int i=0;i<6;i++){Runnable r = ()->{try {s.acquire(); // 获取许可System.out.println(Thread.currentThread().getName()+", 抢优惠劵");Thread.sleep(new Random().nextInt(20)*1000);System.out.println(Thread.currentThread().getName()+", 离开现场");} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{s.release(); // 释放许可}};new Thread(r).start();}}}
运行结果:
5. 无锁机制
无锁编程通过CAS(Compare And Swap)操作实现线程安全,避免了锁的开销。Java中的Atomic类就是无锁机制的典型实现。
package com.demo3;import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;public class Test {// 原子锁,就是无锁private static AtomicInteger count = new AtomicInteger(0);public static void inc() {try {Thread.sleep(1);// 毫秒count.getAndIncrement();//count加1// TimeUnit.MILLISECONDS.sleep(1);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static void main(String[] args) {CountDownLatch cd = new CountDownLatch(100);for (int i = 0; i < 100; i++) {Runnable r = () -> {Test.inc();cd.countDown();};new Thread(r).start();}try {cd.await();System.out.println("总和为:" + Test.count);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
运行结果: