lock() 方法获取哪个对象的锁?
lock() method acquires locks on which object?
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
Lock lck=new ReentrantLock();
public void lockIt(){
lck.lock();
for(int i=0;i<10;i++) {
System.out.println("i : "+ i);
try{Thread.sleep(200);} catch (Exception e){}
}
lck.unlock();
}
public void test()
{
synchronized(this) **// mark 1**
{
for(int j=0;j<10;j++)
{
System.out.println("val is"+j);
try{Thread.sleep(200);}catch (Exception e){}
}
}
}
public static void main(String[] args) {
LockTest obj=new LockTest();
new Thread(new Runnable() {
@Override
public void run() {
obj.lockIt();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
obj.test();
}
}).start();
}
}
}
// 在上面的例子中,当我们说 lck.lock();然后获取锁
实际上是哪个对象?是 "this" 还是 "lck" 本身?
即使在 "this" 或 "lck" 对象上获得了锁
那么有何不同。线程能够进入临界区
被同一个 "this" 或 "lck" 对象锁定。
案例 1:当我们在 mark1.. 处使用 synchronized(this) 时
情况 2:当我们在标记 1..
处使用 synchronized(lck )
在这两种情况下,两个循环并行运行。
lck.lock()
获得的锁(在lck
对象上)与synchronized(this)
或synchronized(lck)
获得的锁完全无关。
如果要保护临界区,那么所有线程都必须使用相同的锁定机制(和相同的锁)。
java.util.concurrent.locks.Lock
是针对 synchronized
关键字不够灵活的情况引入的不同机制。特别是,synchronized
关键字在执行进入和离开块时自动获取和释放锁。不可能在一个方法中获得锁,将其存储在某个地方,离开该方法并在稍后释放锁。使用 Lock
对象,您可以执行这些操作(它还提供锁定等待超时,而 synchronized
可能会永远阻塞)。
@Thilo 已经回答了大部分,只是从你的代码中补充一点,确保你在 finally 块中解锁 如下所示,否则,有一个您可能会遇到 死锁。
public void lockIt(){
lck.lock();
try {
for(int i=0;i<10;i++) {
System.out.println("i : "+ i);
try{Thread.sleep(200);}catch (Exception e){}
}
} finally { //important
if(lck != null) {
lck.unlock();
}
}
}
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
Lock lck=new ReentrantLock();
public void lockIt(){
lck.lock();
for(int i=0;i<10;i++) {
System.out.println("i : "+ i);
try{Thread.sleep(200);} catch (Exception e){}
}
lck.unlock();
}
public void test()
{
synchronized(this) **// mark 1**
{
for(int j=0;j<10;j++)
{
System.out.println("val is"+j);
try{Thread.sleep(200);}catch (Exception e){}
}
}
}
public static void main(String[] args) {
LockTest obj=new LockTest();
new Thread(new Runnable() {
@Override
public void run() {
obj.lockIt();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
obj.test();
}
}).start();
}
}
} // 在上面的例子中,当我们说 lck.lock();然后获取锁 实际上是哪个对象?是 "this" 还是 "lck" 本身?
即使在 "this" 或 "lck" 对象上获得了锁 那么有何不同。线程能够进入临界区 被同一个 "this" 或 "lck" 对象锁定。
案例 1:当我们在 mark1.. 处使用 synchronized(this) 时 情况 2:当我们在标记 1..
处使用 synchronized(lck )在这两种情况下,两个循环并行运行。
lck.lock()
获得的锁(在lck
对象上)与synchronized(this)
或synchronized(lck)
获得的锁完全无关。
如果要保护临界区,那么所有线程都必须使用相同的锁定机制(和相同的锁)。
java.util.concurrent.locks.Lock
是针对 synchronized
关键字不够灵活的情况引入的不同机制。特别是,synchronized
关键字在执行进入和离开块时自动获取和释放锁。不可能在一个方法中获得锁,将其存储在某个地方,离开该方法并在稍后释放锁。使用 Lock
对象,您可以执行这些操作(它还提供锁定等待超时,而 synchronized
可能会永远阻塞)。
@Thilo 已经回答了大部分,只是从你的代码中补充一点,确保你在 finally 块中解锁 如下所示,否则,有一个您可能会遇到 死锁。
public void lockIt(){
lck.lock();
try {
for(int i=0;i<10;i++) {
System.out.println("i : "+ i);
try{Thread.sleep(200);}catch (Exception e){}
}
} finally { //important
if(lck != null) {
lck.unlock();
}
}
}