java 不能引用try里面,为什么不在java中使用带锁的try?

I've read this topic, and this blog article about try with resources locks, as the question popped in my head.

But actually, what I'd rather like would be a try with lock, I mean without lock instantiation. It would release us from the verbose

lock.lock();

try {

//Do some synchronized actions throwing Exception

} finally {

//unlock even if Exception is thrown

lock.unlock();

}

Would rather look like :

? implements Unlockable lock ;

...

try(lock) //implicitly calls lock.lock()

{

//Do some synchronized actions throwing Exception

} //implicitly calls finally{lock.unlock();}

So it would not be a TWR, but just some boilerplate cleaning.

Do you have any technical reasons to suggest describing why this would not be a reasonable idea?

EDIT : to clarify the difference between what I propose and a simple synchronized(lock){} block, check this snippet :

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.ReentrantLock;

public class Test {

public static void main(String[] args) {

ReentrantLock locker =new ReentrantLock();

Condition condition = locker.newCondition();

Thread t1 = new Thread("Thread1") {

@Override

public void run(){

synchronized(locker){

try {

condition.await();

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

}

System.out.println("Thread1 finished");

}

}

} ;

Thread t2 = new Thread("Thread2") {

@Override

public void run(){

synchronized(locker){

Thread.yield();

condition.signal();

System.out.println("blabla2");

}

}

} ;

t1.start();

t2.start();

}

}

Execution will result in a IllegalMonitorStateException, so lock() and unlock() methods are not implicitly called within synchronized block.

解决方案

If you had to deal with a simple case like that, where the pattern of locking/unlocking was limited to a narrow scope like this, you probably don't want to use the more complicated Lock class and probably should just be using the synchronized keyword, instead. That being said, if for some reason you needed this with the more complicated Lock object, it should be relatively straight-forward to create a wrapper around Lock that implements the AutoCloseable interface to be able to do just that. Example:

class AutoUnlock implements AutoCloseable {

private final Lock lock;

public static AutoUnlock lock(Lock lock) {

lock.lock();

return new AutoUnlock(lock);

}

public static AutoUnlock tryLock(Lock lock) {

if (!lock.tryLock()) {

throw new LockNotAcquiredException();

}

return new AutoUnlock(lock);

}

@Override

public void close() {

lock.unlock();

}

private AutoUnlock(Lock lock) {

this.lock = lock;

}

}

With a wrapper like the above, you could then do:

try (AutoUnlock autoUnlock = AutoUnlock.lock(lock)) {

// ... do whatever that requires the lock ...

}

That being said, the Lock class is typically used for very complicated locking scenarios where this wouldn't be particularly useful. For example, Lock objects may be locked in one function in a class and later unlocked in another function (e.g. locking a row in a database in response to an incoming remote procedure call, and then unlocking that row in response to a later RPC), and thus having such a wrapper or making a Lock AutoCloseable, itself, would be of limited use for the way it is actually used. For more simple scenarios, it's more common to just use an existing concurrent datastructure or use synchronized.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值