ReentrantLock可中斷鎖和synchronized區別


ReentrantLock中的lockInterruptibly()方法使得線程可以在被阻塞時響應中斷,比如一個線程t1通過lockInterruptibly()方法獲取到一個可重入鎖,並執行一個長時間的任務,另一個線程通過interrupt()方法就可以立刻打斷t1線程的執行,來獲取t1持有的那個可重入鎖。而通過ReentrantLock的lock()方法或者Synchronized持有鎖的線程是不會響應其他線程的interrupt()方法的,直到該方法主動釋放鎖之后才會響應interrupt()方法。下面看一個示例:

package com.lsl.common.lang;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 測試ReentrantLock可中斷鎖的效果
 */
public class ThreadInteruptExample {
    ReentrantLock lock1=new ReentrantLock();
    ReentrantLock lock2=new ReentrantLock();

    /**
     * ReentrantLock響應中斷
     * @throws Exception
     */
    public void reentrantLockInterupt() throws Exception{
        Thread t1=new Thread(new ReentrantLockTask(lock1,lock2));
        Thread t2=new Thread(new ReentrantLockTask(lock2,lock1));
        t1.start();
        t2.start();
        System.out.println(t1.getName()+"中斷");
        //主線程睡眠1秒,避免線程t1直接響應run方法中的睡眠中斷
        Thread.sleep(1000);
        t1.interrupt();
        //阻塞主線程,避免所有線程直接結束,影響死鎖效果
        Thread.sleep(10000);
    }


    /**
     * Synchronized響應中斷
     * @throws Exception
     */
    public void synchronizedInterupt() throws Exception{
        Object syn1=new Object();
        Object syn2=new Object();
        Thread t1=new Thread(new SynchronizedTask(syn1,syn2));
        Thread t2=new Thread(new SynchronizedTask(syn2,syn1));
        t1.start();
        t2.start();
        System.out.println(t1.getName()+"中斷");
        //主線程睡眠1秒,避免線程t1直接響應run方法中的睡眠中斷
        Thread.sleep(1000);
        t1.interrupt();
        //阻塞主線程,避免所有線程直接結束,影響死鎖效果
        Thread.sleep(1000);
    }

    /**
     * ReentrantLock實現死鎖
     */
    static class ReentrantLockTask implements Runnable{

        ReentrantLock lock1;
        ReentrantLock lock2;

        public ReentrantLockTask(ReentrantLock lock1, ReentrantLock lock2){
            this.lock1=lock1;
            this.lock2=lock2;
        }

        @Override
        public void run() {
            try {
                //可中斷的獲取鎖
                lock1.lockInterruptibly();
                //lock1.lock();
                //睡眠200毫秒,保證兩個線程分別已經獲取到兩個鎖,實現相互的鎖等待
                TimeUnit.MILLISECONDS.sleep(200);
                //lock2.lock();
                //可中斷的獲取鎖
                lock2.lockInterruptibly();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                lock1.unlock();
                lock2.unlock();
                System.out.println("線程"+Thread.currentThread().getName()+"正常結束");
            }

        }
    }

    /**
     * Synchronized實現死鎖
     */
    static class SynchronizedTask implements Runnable{

        Object lock1;
        Object lock2;

        public SynchronizedTask(Object lock1, Object lock2){
            this.lock1=lock1;
            this.lock2=lock2;
        }

        @Override
        public void run() {
            try {
                synchronized (lock1){
                    //睡眠200毫秒,再獲取另一個鎖,
                    //保證兩個線程分別已經獲取到兩個鎖,實現相互的鎖等待
                    Thread.sleep(200);
                    synchronized (lock2){
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                System.out.println("線程"+Thread.currentThread().getName()+"正常結束");
            }

        }
    }

    public static void main(String[] args) throws Exception {
        ThreadInteruptExample demo=new ThreadInteruptExample();
        ThreadInteruptExample demo1=new ThreadInteruptExample();
        demo.reentrantLockInterupt();
        demo1.synchronizedInterupt();
    }

}

  響應中斷

 

 執行完畢才響應中斷-現象死鎖

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM