学习Lock的阻塞式调用

https://blog.csdn.net/luzhouyue1024/article/details/128589928

Java使用synchronized关键字实现了临界代码区的原子性与可见性并发安全,为什么还需要Lock类呢?https://blog.csdn.net/luzhouyue1024/article/details/128589928

在"Java Concurrency in Practice"一书中,作者提到,“内置锁synchronized无法中断一个正在等待获取锁的线程,并无法实现非阻塞结构的加锁规则”。

下面用一个实验展示synchronized非阻塞的行为.

package lydia.study.concurrent;
 
public class SynchronizedTest {
    //测试synchronized不响应中断
    public static void testSynchronized() {
        Object o = new Object();
 
        Thread t1 = new Thread(){
            public void run () {
                synchronized (o) {
                    try {
                        System.out.println("Thread t1 get the synchronized lock");
                        Thread.sleep(5000);
                        System.out.println("Thread t1结束休眠");
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    } finally {
                        System.out.println("Thread t1退出");
                    }
                }
            }
        };
        t1.start();
 
        Thread t2 = new Thread() {
            public void run() {
                synchronized (o) {
                    System.out.println("Thread t2 get the synchronized lock");
                }
            }
        };
        t2.start();
        System.out.println("尝试对线程2中断");
        t2.interrupt();
        System.out.println("main结束");
    }
 
    public static void main(String[] args) throws InterruptedException {
        testSynchronized();
    }
}

运行结果如下

尝试对线程2中断
main结束
Thread t1 get the synchronized lock
Thread t1结束休眠
Thread t1退出
Thread t2 get the synchronized lock

线程t1先创建并运行,获取synchronized锁,然后休眠5秒钟;此时线程t2也被创建,它1同样想获取synchronized锁,但是由于锁在t1手中,只能等待t1结束运行再获得锁并打印出"Thread t2 get the synchronized lock"。注意,主线程尝试了以下这句代码,想中断t2,但是t2并没有响应中断。

t2.interrupt();

为了使得一个线程在等待锁的时候,能够响应中断,Lock接口的lockInterruptibly()方法提供了可响应中断的行为。让我们看下一个实验

package lydia.study.concurrent;
 
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
 
public class LockTest {
 
    //lock的interruptibly在线程阻塞并等待锁的时候,能响应中断
    public static void lockInterruptibly() throws InterruptedException {
        Object o = new Object();
        Lock lockO = new ReentrantLock();
        Thread t1 = new Thread(){
            public void run () {
                {
                    try {
                        lockO.lockInterruptibly();
                        System.out.println("Thread t1 get the lock");
                        Thread.sleep(5000);
                        System.out.println("Thread t1结束休眠");
                    } catch (InterruptedException e) {
                        System.out.println("Thread t1被中断");
                        e.printStackTrace();
                    } finally {
                        lockO.unlock();
                        System.out.println("Thread t1退出");
                    }
                }
            }
        };
        t1.start();
 
        Thread t2 = new Thread() {
            public void run() {
                try {
                    lockO.lockInterruptibly();
                    System.out.println("线程t2 get the lockO");
                }catch (InterruptedException e) {
                    System.out.println("Thread t2被中断");
                    e.printStackTrace();
                } finally {
                    lockO.unlock();
                    System.out.println("Thread t2退出");
                }
 
            }
        };
        Thread.sleep(1000);
        t2.start();
        System.out.println("尝试对线程2中断");
        t2.interrupt();
        System.out.println("main结束");
    }
 
    public static void main(String[] args) throws InterruptedException {
        lockInterruptibly();
    }
}

运行,会得到以下结果

Thread t1 get the lock
尝试对线程2中断
main结束
Thread t2被中断
java.lang.InterruptedException
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1220)
	......
	at lydia.study.concurrent.LockTest$2.run(LockTest.java:41)
Thread t1结束休眠
Thread t1退出

在lockInterruptibly()测试方法中,可以看到t2响应了中断,立刻返回,不再等待 lock的锁。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值