blog » Java/J2EE » 用通俗的语言说说lock和lockInterruptibly的区别

用通俗的语言说说lock和lockInterruptibly的区别

下面的lockInterruptibly()就稍微难理解一些。

先说说线程的打扰机制,每个线程都有一个 打扰 标志。这里分两种情况,

1. 线程在sleep或wait,join, 此时如果别的进程调用此进程的 interrupt()方法,此线程会被唤醒并被要求处理InterruptedException;(thread在做IO操作时也可能有类似行为,见java thread api)
2. 此线程在运行中, 则不会收到提醒。但是 此线程的 “打扰标志”会被设置, 可以通过isInterrupted()查看并 作出处理。

lockInterruptibly()和上面的第一种情况是一样的, 线程在请求lock并被阻塞时,如果被interrupt,则“此线程会被唤醒并被要求处理InterruptedException”。

我写了几个test,验证一下:

1). lock()忽视interrupt(), 拿不到锁就 一直阻塞:

@Test
public void test3() throws Exception{
    final Lock lock=new ReentrantLock();
    lock.lock();
    Thread.sleep(1000);
    Thread t1=new Thread(new Runnable(){
        @Override
        public void run() {
            lock.lock();
            System.out.println(Thread.currentThread().getName()+" interrupted.");
        }
    });
    t1.start();
    Thread.sleep(1000);
    t1.interrupt();
    Thread.sleep(1000000);
}

可以进一步在Eclipse debug模式下观察,子线程一直阻塞。

2). lockInterruptibly()会响应打扰 并catch到InterruptedException

@Test
public void test4() throws Exception{
    final Lock lock=new ReentrantLock();
    lock.lock();
    Thread.sleep(1000);
    Thread t1=new Thread(new Runnable(){
        @Override
        public void run() {
            try {
                lock.lockInterruptibly();
            } catch (InterruptedException e) {
                        System.out.println(Thread.currentThread().getName()+" interrupted.");
            }
        }
    });
    t1.start();
    Thread.sleep(1000);
    t1.interrupt();
    Thread.sleep(1000000);
}

3). 以下实验验证:当线程已经被打扰了(isInterrupted()返回true)。则线程使用lock.lockInterruptibly(),直接会被要求处理InterruptedException。

@Test
public void test5() throws Exception{
    final Lock lock=new ReentrantLock();
    Thread t1=new Thread(new Runnable(){
        @Override
        public void run() {
            try {
                Thread.sleep(2000);
                lock.lockInterruptibly();
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread().getName()+" interrupted.");
            }
        }
    });
    t1.start();
    t1.interrupt();
    Thread.sleep(10000000);
}

[来源:http://www.dewen.org/q/9077]

This post has already been read 1139 times!

Related posts

RSS 2.0 | leave a response | trackback

发表评论