首页 新闻 会员 周边

自定义独占锁失败,究竟是什么原因

0
[待解决问题]

最近在重新学习并发,学到了 独占锁。跟着教程的敲的代码,但是却起不到独占的效果,教程是实现了,我实在不知道问题出现在哪里,请求大神帮忙看看;

// 这是自定义实现的独占锁
class myLock implements Lock {
    //独占锁,
    class Mysync extends AbstractQueuedSynchronizer {
        @Override
        protected boolean tryAcquire(int arg) {
                if (compareAndSetState(0, 1)) {
                    // 成功了表示 锁已经加上了;设置 owner 为当前线程
//                    log.debug("getState(),{}",getState());
                    System.out.println("getState= "+getState());
                    System.out.println("Thread.currentThread()="+Thread.currentThread());
                    setExclusiveOwnerThread(Thread.currentThread());
                    return true;
                }
            return false;
        }

        @Override
        protected boolean tryRelease(int arg) {
            // 顺序一定要这样的,
                setExclusiveOwnerThread(null);
                setState(0);
                return true;
        }

        @Override
        protected boolean isHeldExclusively() {
            return getState() == 1;
        }

        public Condition newCondition() {
            return new ConditionObject();
        }
    }


    private Mysync sync = new Mysync();

    @Override // 加锁 不成功就会进入等待队列等待
    public void lock() {// 不成功,会进入等待队列
        boolean b = sync.tryAcquire(1);
        System.out.println("加锁状态:"+b);
    }

    @Override // 加锁 可打断
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }

    @Override // 尝试加锁 尝试一次
    public boolean tryLock() {
        return sync.tryAcquire(1);
    }

    @Override // 尝试加锁,带超时时间
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(time));
    }

    @Override // 解锁
    public void unlock() {
        sync.release(1);
    }

    @Override // 创建条件变量
    public Condition newCondition() {
        return sync.newCondition();
    }
}


// 这是测试代码:
public class TestApp {
    public static void main(String[] args) {
        myLock lock1 = new myLock();
        new Thread(() -> {
            lock1.lock();
            try {
                log.debug("locking.....");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } finally {
                log.debug("unlocking.....");
                lock1.unlock();
            }


        }, "t1").start();

        new Thread(()->{
            lock1.lock();
            try{
                log.debug("locking.....");
            }finally {
                log.debug("unlocking");
                lock1.unlock();
            }
        },"t2").start();

    }
}


输出内容是:

11:16:46 [DEBUG] [t1] c.l.T.TestApp - locking.....
11:16:46 [DEBUG] [t2] c.l.T.TestApp - locking.....
11:16:46 [DEBUG] [t2] c.l.T.TestApp - unlocking
11:16:47 [DEBUG] [t1] c.l.T.TestApp - unlocking.....

按道理既然是独占锁,将就应该 t2 在 t1 unlock 之后才能去 lock 啊,实在不知道问题到底出现在什么地方了

lukely的主页 lukely | 初学一级 | 园豆:147
提问于:2022-01-12 11:23
< >
分享
所有回答(1)
1

@Override // 加锁 不成功就会进入等待队列等待
public void lock() {// 不成功,会进入等待队列
boolean b = sync.tryAcquire(1);
System.out.println("加锁状态:"+b);
}

这里调用方法调用错了 应该调用 sync.acquire(1);

lukely | 园豆:147 (初学一级) | 2022-01-12 12:53
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册