AQS互斥锁

来源:互联网 发布:java敏捷开发平台 编辑:程序博客网 时间:2024/06/08 13:18


实现单机版任务调度的功能(分布式后续考虑,暂时先单进程)

1.首先管理员启动整个任务,并设置执行权限

2.工作节点收到消息后就会创建对应的线程,并开始执行任务(任务都是由一个管理员进行分配)

3.运行过程中管理员需要临时中断某个任务,需要设置一个互斥信号,此时对应的工作节点都需要被阻塞,注意不是完全销毁

自己总结一句话(例如有多个线程同时工作时候,设置一个变量,控制这些线程阻塞,或者活动)

import java.util.concurrent.TimeUnit;import java.util.concurrent.TimeoutException;import java.util.concurrent.locks.AbstractQueuedSynchronizer;/** * 实现一个互斥实现,基于Cocurrent中的{@linkplain AbstractQueuedSynchronizer}实现了自己的sync <br/> * 应用场景:系统初始化/授权控制,没权限时阻塞等待。有权限时所有线程都可以快速通过 *  * <pre> * false : 代表需要被阻塞挂起,等待mutex变为true被唤醒 * true : 唤醒被阻塞在false状态下的thread *  * BooleanMutex mutex = new BooleanMutex(true); * try { *     mutex.get(); //当前状态为true, 不会被阻塞 * } catch (InterruptedException e) { *     // do something * } *  * mutex.set(false); * try { *     mutex.get(); //当前状态为false, 会被阻塞直到另一个线程调用mutex.set(true); * } catch (InterruptedException e) { *     // do something * } * </pre> *  */public class BooleanMutex {private Sync sync;public BooleanMutex() {sync = new Sync();set(false);}public BooleanMutex(Boolean mutex) {sync = new Sync();set(mutex);}/** * 阻塞等待Boolean为true *  * @throws InterruptedException */public void get() throws InterruptedException {sync.innerGet();}/** * 阻塞等待Boolean为true,允许设置超时时间 *  * @param timeout * @param unit * @throws InterruptedException * @throws TimeoutException */public void get(long timeout, TimeUnit unit) throws InterruptedException,TimeoutException {sync.innerGet(unit.toNanos(timeout));}/** * 重新设置对应的Boolean mutex *  * @param mutex */public void set(Boolean mutex) {if (mutex) {sync.innerSetTrue();} else {sync.innerSetFalse();}}public boolean state() {return sync.innerState();}/** * Synchronization control for BooleanMutex. Uses AQS sync state to * represent run status */private final class Sync extends AbstractQueuedSynchronizer {private static final long serialVersionUID = -7828117401763700385L;/** State value representing that TRUE */private static final int TRUE = 1;/** State value representing that FALSE */private static final int FALSE = 2;private boolean isTrue(int state) {return (state & TRUE) != 0;}/** * 实现AQS的接口,获取共享锁的判断 */@Overrideprotected int tryAcquireShared(int state) {// 如果为true,直接允许获取锁对象// 如果为false,进入阻塞队列,等待被唤醒return isTrue(getState()) ? 1 : -1;}/** * 实现AQS的接口,释放共享锁的判断 */@Overrideprotected boolean tryReleaseShared(int ignore) {// 始终返回true,代表可以releasereturn true;}boolean innerState() {return isTrue(getState());}void innerGet() throws InterruptedException {super.acquireSharedInterruptibly(0);}void innerGet(long nanosTimeout) throws InterruptedException,TimeoutException {if (!super.tryAcquireSharedNanos(0, nanosTimeout))throw new TimeoutException();}void innerSetTrue() {for (;;) {int s = getState();if (s == TRUE) {return; // 直接退出}if (super.compareAndSetState(s, TRUE)) {// cas更新状态,避免并发更新true操作releaseShared(0);// 释放一下锁对象,唤醒一下阻塞的Thread}}}void innerSetFalse() {for (;;) {int s = getState();if (s == FALSE) {return; // 直接退出}if (super.compareAndSetState(s, FALSE)) {// cas更新状态,避免并发更新false操作setState(FALSE);}}}}}

测试代码

    @Test    public void test_init_true() {        BooleanMutex mutex = new BooleanMutex(true);        try {            mutex.get(); //不会被阻塞        } catch (InterruptedException e) {            want.fail();        }    }    @Test    public void test_init_false() {        final BooleanMutex mutex = new BooleanMutex(false);        try {            final CountDownLatch count = new CountDownLatch(1);            ExecutorService executor = Executors.newCachedThreadPool();            executor.submit(new Callable() {                public Object call() throws Exception {                    Thread.sleep(1000);                    mutex.set(true);                    count.countDown();                    return null;                }            });            mutex.get(); //会被阻塞,等异步线程释放锁对象            count.await();            executor.shutdown();        } catch (InterruptedException e) {            want.fail();        }    }    @Test    public void test_concurrent_true() {        try {            final BooleanMutex mutex = new BooleanMutex(true);            final CountDownLatch count = new CountDownLatch(10);            ExecutorService executor = Executors.newCachedThreadPool();            for (int i = 0; i < 10; i++) {                executor.submit(new Callable() {                    public Object call() throws Exception {                        mutex.get();                        count.countDown();                        return null;                    }                });            }            count.await();            executor.shutdown();        } catch (InterruptedException e) {            want.fail();        }    }    @Test    public void test_concurrent_false() {        try {            final BooleanMutex mutex = new BooleanMutex(false);//初始为false            final CountDownLatch count = new CountDownLatch(10);            ExecutorService executor = Executors.newCachedThreadPool();            for (int i = 0; i < 10; i++) {                executor.submit(new Callable() {                    public Object call() throws Exception {                        mutex.get();//被阻塞                        count.countDown();                        return null;                    }                });            }            Thread.sleep(1000);            mutex.set(true);            count.await();            executor.shutdown();        } catch (InterruptedException e) {            want.fail();        }    }


0 0
原创粉丝点击