ロックとは何ですか?なぜロックが必要なのですか?
锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时
访问共享资源(但是有些锁可以允许多个线程并发的访问共享资源,比如读写锁).
在Lock接口出现之前,Java程序是靠synchronized关键字实现锁功能的,而Java SE 5之后,并发包中新增
了Lock接口(以及相关实现类)用来实现锁功能,它提供了与synchronized关键字类似的同步功
能,只是在使用时需要显式地获取和释放锁.
虽然它缺少了(通过synchronized块或者方法所提供的)隐式获取释放锁的便捷性,
但是却拥有了锁获取与释放的可操作性、可中断的获取锁以及超时获取锁等多种synchronized关键字所不具备的同步特性.
使用synchronized关键字将会隐式地获取锁,但是它将锁的获取和释放固化了,也就是先获取再释放,
当然,这种方式简化了同步的管理,可是扩展性没有显示的锁获取和释放来的好
ロックの使用:
Lock lock = new ReentrantLock();
lock.lock(); // 加锁
try{
// do something
}finally{
lock.unlock(); // 解锁
}
なぜlock.lock()ロックコードを試してはいけないのですか?
ロック操作が例外をスローする可能性があるため
通常の状況(推奨):ロック操作はtryブロックの前にあり、例外が発生するとtry-finallyブロックは実行されず、例外のためにプログラムが直接中断されます。
推奨されません:ロック操作はtryブロック内にあります。tryブロックが実行されているため、tryで例外が発生した場合でもfinallyは引き続き実行されます。このとき、try内のロック操作が異常な場合、finallyは引き続きロック解除操作を実行します。このとき、ロックは取得されていないため、ロック解除操作を実行すると別の例外がスローされます。すべての例外がスローされますが、最終的にロック解除でスローされた例外情報により、ロックされた例外情報が上書きされ、情報が失われます
最終的に試行する前に、lock.lock()をコードブロックの前に追加できますか?はい、理由を説明し、いいえ、理由を説明します。
いいえ、理由は、try-finallyの前にコードブロックに例外がある場合、プログラムはtry-finally領域に移動せず、lock.lock()操作が異常なコードブロックの前に実行されるためです。例外のため、プログラムは終了します。このとき、前回追加したロックが最終的に正常に解除されず、デッドロックが発生する場合があります
Synchronizedと比較したLockの新機能
Lock APIが提供するメソッド