1. 程式人生 > >ReentrantLock與synchronized的區別 ( by quqi99 )

ReentrantLock與synchronized的區別 ( by quqi99 )

                                    ReentrantLock與synchronized的區別(by quqi99)

作者:張華 發表於:2010-02-08

       ReentrantLock 的lock機制有2種,忽略中斷鎖和響應中斷鎖,這給我們帶來了很大的靈活性。比如:如果A、B2個執行緒去競爭鎖,A執行緒得到了鎖,B執行緒等待,但是A執行緒這個時候實在有太多事情要處理,就是 一直不返回,B執行緒可能就會等不及了,想中斷自己,不再等待這個鎖了,轉而處理其他事情。這個時候ReentrantLock 就提供了2種機制,第一,B執行緒中斷自己(或者別的執行緒中斷它),但是ReentrantLock

不去響應,繼續讓B執行緒等待,你再怎麼中斷,我全當耳邊風(synchronized原語就是如此);第二,B執行緒中斷自己(或者別的執行緒中斷它),ReentrantLock 處理了這個中斷,並且不再等待這個鎖的到來,完全放棄。請看例子:

/**
 * @version 0.10 2009-11-6
 * @author Zhang Hua
 */
public class Test {
    //是用ReentrantLock,還是用synchronized
    public static boolean useSynchronized = false;
    public static void main(String[] args) {
        IBuffer buff = null;
        if(useSynchronized){
            buff = new Buffer();
        }else{
            buff = new BufferInterruptibly();   
        }
        final Writer writer = new Writer(buff);
        final Reader reader = new Reader(buff);
        writer.start();
        reader.start();
        new Thread(new Runnable() {
            public void run() {
                long start = System.currentTimeMillis();
                for (;;) {
                    // 等5秒鐘去中斷讀
                    if (System.currentTimeMillis() - start > 5000) {
                        System.out.println("不等了,嘗試中斷");
                        reader.interrupt();
                        break;
                    }

                }

            }
        }).start();
    }
}

interface IBuffer{
    public void write();
    public void read() throws InterruptedException;
}
class Buffer implements IBuffer{
    private Object lock;

    public Buffer() {
        lock = this;
    }

    public void write() {
        synchronized (lock) {
            long startTime = System.currentTimeMillis();
            System.out.println("開始往這個buff寫入資料…");
            for (;;)// 模擬要處理很長時間
            {
                if (System.currentTimeMillis() - startTime > Integer.MAX_VALUE)
                    break;
            }
            System.out.println("終於寫完了");
        }
    }

    public void read() {
        synchronized (lock) {
            System.out.println("從這個buff讀資料");
        }
    }
}

class BufferInterruptibly implements IBuffer{

    private ReentrantLock lock = new ReentrantLock();

    public void write() {
        lock.lock();
        try {
            long startTime = System.currentTimeMillis();
            System.out.println("開始往這個buff寫入資料…");
            for (;;)// 模擬要處理很長時間
            {
                if (System.currentTimeMillis() - startTime > Integer.MAX_VALUE)
                    break;
            }
            System.out.println("終於寫完了");
        } finally {
            lock.unlock();
        }
    }

    public void read() throws InterruptedException{
        lock.lockInterruptibly();// 注意這裡,可以響應中斷
        try {
            System.out.println("從這個buff讀資料");
        } finally {
            lock.unlock();
        }
    }

}

class Writer extends Thread {

    private IBuffer buff;

    public Writer(IBuffer buff) {
        this.buff = buff;
    }

    @Override
    public void run() {
        buff.write();
    }

}

class Reader extends Thread {

    private IBuffer buff;

    public Reader(IBuffer buff) {
        this.buff = buff;
    }

    @Override
    public void run() {

        try {
            buff.read();
        } catch (InterruptedException e) {
            System.out.println("我不讀了");  
        }

        System.out.println("讀結束");

    }
}